├── LICENSE.README ├── MANIFEST ├── MANIFEST.SKIP ├── Makefile.PL ├── README.INSTALL ├── README.pod ├── bin ├── app.pl ├── example_init.sh └── worker.pl ├── config.yml ├── environments ├── development.yml └── production.yml ├── lib ├── LibreMailer.pm └── LibreMailer │ ├── Campaigns.pm │ ├── Contacts.pm │ ├── DateTime.pm │ ├── EncodeSafeURL.pm │ ├── Lists.pm │ ├── RestClient.pm │ ├── Roles.pm │ ├── Statistics.pm │ ├── Tracker.pm │ ├── Users.pm │ └── Worker.pm ├── logs └── production.log ├── public ├── 404.html ├── 500.html ├── Chart.js-master │ ├── .gitignore │ ├── Chart.js │ ├── Chart.min.js │ ├── LICENSE.md │ ├── README.md │ ├── bower.json │ ├── docs │ │ ├── 00-Getting-Started.md │ │ ├── 01-Line-Chart.md │ │ ├── 02-Bar-Chart.md │ │ ├── 03-Radar-Chart.md │ │ ├── 04-Polar-Area-Chart.md │ │ ├── 05-Pie-Doughnut-Chart.md │ │ ├── 06-Advanced.md │ │ └── 07-Notes.md │ ├── gulpfile.js │ ├── package.json │ ├── samples │ │ ├── bar.html │ │ ├── doughnut.html │ │ ├── line.html │ │ ├── pie.html │ │ ├── polar-area.html │ │ └── radar.html │ └── src │ │ ├── Chart.Bar.js │ │ ├── Chart.Core.js │ │ ├── Chart.Doughnut.js │ │ ├── Chart.Line.js │ │ ├── Chart.PolarArea.js │ │ └── Chart.Radar.js ├── bootstrap-3.1.1-dist │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ └── bootstrap.min.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ └── js │ │ ├── bootstrap.js │ │ └── bootstrap.min.js ├── css │ ├── bootstrap-select.min.css │ ├── error.css │ ├── style-1.0.css │ └── style.css ├── datetimepicker-master │ ├── .gitignore │ ├── MIT-LICENSE.txt │ ├── README.md │ ├── bower.json │ ├── datetimepicker.jquery.json │ ├── index.html │ ├── jquery.datetimepicker.css │ ├── jquery.datetimepicker.js │ ├── jquery.js │ └── screen │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.1.png │ │ └── 3.png ├── dispatch.cgi ├── dispatch.fcgi ├── favicon.ico ├── font-awesome-4.0.3 │ ├── css │ │ ├── font-awesome.css │ │ └── font-awesome.min.css │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ └── fontawesome-webfont.woff │ ├── less │ │ ├── bordered-pulled.less │ │ ├── core.less │ │ ├── fixed-width.less │ │ ├── font-awesome.less │ │ ├── icons.less │ │ ├── larger.less │ │ ├── list.less │ │ ├── mixins.less │ │ ├── path.less │ │ ├── rotated-flipped.less │ │ ├── spinning.less │ │ ├── stacked.less │ │ └── variables.less │ └── scss │ │ ├── _bordered-pulled.scss │ │ ├── _core.scss │ │ ├── _fixed-width.scss │ │ ├── _icons.scss │ │ ├── _larger.scss │ │ ├── _list.scss │ │ ├── _mixins.scss │ │ ├── _path.scss │ │ ├── _rotated-flipped.scss │ │ ├── _spinning.scss │ │ ├── _stacked.scss │ │ ├── _variables.scss │ │ └── font-awesome.scss ├── images │ ├── gradient.jpg │ ├── logo.png │ ├── logo_medium.png │ ├── logo_small.png │ ├── logo_xsmall.png │ ├── perldancer-bg.jpg │ ├── perldancer.jpg │ └── track.gif ├── javascripts │ ├── Chart.js-master │ │ ├── .gitignore │ │ ├── Chart.js │ │ ├── Chart.min.js │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── bower.json │ │ ├── docs │ │ │ ├── 00-Getting-Started.md │ │ │ ├── 01-Line-Chart.md │ │ │ ├── 02-Bar-Chart.md │ │ │ ├── 03-Radar-Chart.md │ │ │ ├── 04-Polar-Area-Chart.md │ │ │ ├── 05-Pie-Doughnut-Chart.md │ │ │ ├── 06-Advanced.md │ │ │ └── 07-Notes.md │ │ ├── gulpfile.js │ │ ├── package.json │ │ ├── samples │ │ │ ├── bar.html │ │ │ ├── doughnut.html │ │ │ ├── line.html │ │ │ ├── pie.html │ │ │ ├── polar-area.html │ │ │ └── radar.html │ │ └── src │ │ │ ├── Chart.Bar.js │ │ │ ├── Chart.Core.js │ │ │ ├── Chart.Doughnut.js │ │ │ ├── Chart.Line.js │ │ │ ├── Chart.PolarArea.js │ │ │ └── Chart.Radar.js │ ├── bootstrap-select.min.js │ ├── jquery-2.1.1.min.js │ ├── jquery-ui-1.10.4.min.js │ └── jquery.min.js └── tinymce │ ├── LICENSE.TXT │ ├── changelog.txt │ └── js │ └── tinymce │ ├── jquery.tinymce.min.js │ ├── langs │ └── readme.md │ ├── license.txt │ ├── plugins │ ├── advlist │ │ └── plugin.min.js │ ├── anchor │ │ └── plugin.min.js │ ├── autolink │ │ └── plugin.min.js │ ├── autoresize │ │ └── plugin.min.js │ ├── autosave │ │ └── plugin.min.js │ ├── bbcode │ │ └── plugin.min.js │ ├── charmap │ │ └── plugin.min.js │ ├── code │ │ └── plugin.min.js │ ├── colorpicker │ │ └── plugin.min.js │ ├── contextmenu │ │ └── plugin.min.js │ ├── directionality │ │ └── plugin.min.js │ ├── emoticons │ │ ├── img │ │ │ ├── smiley-cool.gif │ │ │ ├── smiley-cry.gif │ │ │ ├── smiley-embarassed.gif │ │ │ ├── smiley-foot-in-mouth.gif │ │ │ ├── smiley-frown.gif │ │ │ ├── smiley-innocent.gif │ │ │ ├── smiley-kiss.gif │ │ │ ├── smiley-laughing.gif │ │ │ ├── smiley-money-mouth.gif │ │ │ ├── smiley-sealed.gif │ │ │ ├── smiley-smile.gif │ │ │ ├── smiley-surprised.gif │ │ │ ├── smiley-tongue-out.gif │ │ │ ├── smiley-undecided.gif │ │ │ ├── smiley-wink.gif │ │ │ └── smiley-yell.gif │ │ └── plugin.min.js │ ├── example │ │ ├── dialog.html │ │ └── plugin.min.js │ ├── example_dependency │ │ └── plugin.min.js │ ├── fullpage │ │ └── plugin.min.js │ ├── fullscreen │ │ └── plugin.min.js │ ├── hr │ │ └── plugin.min.js │ ├── image │ │ └── plugin.min.js │ ├── importcss │ │ └── plugin.min.js │ ├── insertdatetime │ │ └── plugin.min.js │ ├── layer │ │ └── plugin.min.js │ ├── legacyoutput │ │ └── plugin.min.js │ ├── link │ │ └── plugin.min.js │ ├── lists │ │ └── plugin.min.js │ ├── media │ │ ├── moxieplayer.swf │ │ └── plugin.min.js │ ├── nonbreaking │ │ └── plugin.min.js │ ├── noneditable │ │ └── plugin.min.js │ ├── pagebreak │ │ └── plugin.min.js │ ├── paste │ │ └── plugin.min.js │ ├── preview │ │ └── plugin.min.js │ ├── print │ │ └── plugin.min.js │ ├── save │ │ └── plugin.min.js │ ├── searchreplace │ │ └── plugin.min.js │ ├── spellchecker │ │ └── plugin.min.js │ ├── tabfocus │ │ └── plugin.min.js │ ├── table │ │ └── plugin.min.js │ ├── template │ │ └── plugin.min.js │ ├── textcolor │ │ └── plugin.min.js │ ├── textpattern │ │ └── plugin.min.js │ ├── visualblocks │ │ ├── css │ │ │ └── visualblocks.css │ │ └── plugin.min.js │ ├── visualchars │ │ └── plugin.min.js │ └── wordcount │ │ └── plugin.min.js │ ├── skins │ └── lightgray │ │ ├── content.inline.min.css │ │ ├── content.min.css │ │ ├── fonts │ │ ├── readme.md │ │ ├── tinymce-small.dev.svg │ │ ├── tinymce-small.eot │ │ ├── tinymce-small.svg │ │ ├── tinymce-small.ttf │ │ ├── tinymce-small.woff │ │ ├── tinymce.dev.svg │ │ ├── tinymce.eot │ │ ├── tinymce.svg │ │ ├── tinymce.ttf │ │ └── tinymce.woff │ │ ├── img │ │ ├── anchor.gif │ │ ├── loader.gif │ │ ├── object.gif │ │ └── trans.gif │ │ ├── skin.ie7.min.css │ │ └── skin.min.css │ ├── themes │ └── modern │ │ └── theme.min.js │ └── tinymce.min.js ├── sql └── libremailer.sql ├── t ├── 001_base.t ├── 002_index.t ├── 003_campaigns.t ├── 004_contacts.t ├── 005_lists.t ├── 006_roles.t ├── 007_statistics.t ├── 008_users.t ├── 009_datetime.t ├── 010_encode_safe_url.t ├── 011_worker.t └── 012_tracker.t ├── uploads └── readme.txt └── views ├── 404.tt ├── campaigns.tt ├── contacts.tt ├── data └── readme.txt ├── denied.tt ├── index.tt ├── layouts └── main.tt ├── lists.tt ├── login.tt ├── report.tt ├── roles.tt ├── statistics.tt ├── statistics_bounces.tt ├── statistics_links.tt ├── statistics_opens.tt ├── statistics_unsubscribes.tt ├── unsubscribe.tt ├── upload.tt └── users.tt /MANIFEST.SKIP: -------------------------------------------------------------------------------- 1 | ^\.git\/ 2 | maint 3 | ^tags$ 4 | .last_cover_stats 5 | Makefile$ 6 | ^blib 7 | ^pm_to_blib 8 | ^.*.bak 9 | ^.*.old 10 | ^t.*sessions 11 | ^cover_db 12 | ^.*\.log 13 | ^.*\.swp$ 14 | -------------------------------------------------------------------------------- /Makefile.PL: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use ExtUtils::MakeMaker; 4 | 5 | # Normalize version strings like 6.30_02 to 6.3002, 6 | # so that we can do numerical comparisons on it. 7 | my $eumm_version = $ExtUtils::MakeMaker::VERSION; 8 | $eumm_version =~ s/_//; 9 | 10 | WriteMakefile( 11 | NAME => 'LibreMailer', 12 | AUTHOR => q{Sarah Fuller }, 13 | VERSION_FROM => 'lib/LibreMailer.pm', 14 | ABSTRACT => 'Email Marketing App', 15 | ($eumm_version >= 6.3001 16 | ? ('LICENSE'=> 'perl') 17 | : ()), 18 | PL_FILES => {}, 19 | PREREQ_PM => { 20 | 'Test::More' => 0, 21 | 'YAML' => 0, 22 | 'Dancer' => 1.3126, 23 | 'Template' => 0, 24 | 'Try::Tiny' => 0, 25 | 'strictures' => 0, 26 | 'DateTime' => 0, 27 | 'DateTime::Format::MySQL' => 0, 28 | 'Email::Valid' => 0, 29 | 'JSON' => 0, 30 | 'JSON::Any' => 0, 31 | 'Dancer::Template::TemplateToolkit' => 0, 32 | 'Dancer::Session::Cookie' => 0, 33 | 'Dancer::Plugin::REST' => 0, 34 | 'Dancer::Plugin::Passphrase' => 0, 35 | 'Dancer::Plugin::Database' => 0, 36 | 'Dancer::Plugin::FlashMessage' => 0, 37 | 'Data::Dumper' => 0, 38 | 'DBD::mysql' => 0, 39 | 'Plack::Runner' => 0, 40 | 'Plack::Handler::Starman' => 0, 41 | 'Parallel::ForkManager' => 0, 42 | 'HTML::LinkExtractor' => 0, 43 | 'Email::Stuff' => 0, 44 | 'Email::Send' => 0, 45 | 'Email::Valid' => 0, 46 | 'Mail::POP3Client' => 0, 47 | 'IO::Socket::SSL' => 0, 48 | 'Mail::DeliveryStatus::BounceParser' => 0, 49 | 'Text::CSV' => 0, 50 | 'Dancer::Plugin::SimpleCRUD' => 0, 51 | 'Dancer::Plugin::Auth::Extensible' => 0, 52 | 'Moo' => 0, 53 | 'MIME::Base64::URLSafe' => 0, 54 | 'Crypt::CBC' => 0, 55 | 'Crypt::Blowfish' => 0, 56 | }, 57 | dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, 58 | clean => { FILES => 'LibreMailer-*' }, 59 | ); 60 | -------------------------------------------------------------------------------- /README.pod: -------------------------------------------------------------------------------- 1 | =pod 2 | 3 | =head1 Libre Mailer 4 | 5 | Libre Mailer is a modest and simple web based email marketing application. The entire app was made in only one weekend to prove a point, procrastinate from real work but most importantly stave off boredom. 6 | While it might have been knocked out over a weekend and thus a bit light on features it does work! It does send out email campaigns and produces statistics (open statistics, Link statistics, Bounce statistics) etc. 7 | 8 | 9 | =head2 Website demo 10 | 11 | http://libremailer.averna.id.au/ 12 | 13 | Login: admin 14 | Password: admin 15 | 16 | The database is reset every twelve hours. 17 | 18 | =head2 Install 19 | 20 | 21 | SEE: INSTALL.README 22 | 23 | 24 | 25 | =head2 Feedback / Reporting bugs / Contact 26 | 27 | This was a weekend project for the fun of it. I'll fix any serious bugs if someone is ACTUALLY using this but I make no promises regarding any new features. 28 | 29 | 30 | =head2 Acknowledgements 31 | 32 | This app uses a lot of other outstanding open source projects and without them it wouldn't have been possible. 33 | 34 | 35 | =head2 License 36 | 37 | LibreMailer copyright (C) 2014 Sarah Fuller 38 | 39 | See LICENSE.README for a full copy of the GPLv3 license. 40 | 41 | This program is free software: you can redistribute it and/or modify 42 | it under the terms of the GNU General Public License as published by 43 | the Free Software Foundation, either version 3 of the License, or 44 | (at your option) any later version. 45 | 46 | This program is distributed in the hope that it will be useful, 47 | but WITHOUT ANY WARRANTY; without even the implied warranty of 48 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 49 | GNU General Public License for more details. 50 | 51 | You should have received a copy of the GNU General Public License 52 | along with this program. If not, see . 53 | 54 | 55 | =cut 56 | -------------------------------------------------------------------------------- /bin/app.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use Dancer; 3 | use LibreMailer; 4 | dance; 5 | -------------------------------------------------------------------------------- /bin/example_init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # EXAMPLE INIT SCRIPT FOR DANCER APP 4 | # 5 | # chkconfig: - 80 30 6 | # description: Perl Dancer web app 7 | # 8 | # Perl Dancer web app 9 | # 10 | 11 | 12 | PERL="/home/libremailer/perl5/perlbrew/perls/perl-5.18.2_WITH_THREADS/bin/perl -X" 13 | PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" 14 | APP_HOME="/home/libremailer/app" 15 | DAEMON="$APP_HOME/bin/app.pl" 16 | PLACKUP="/usr/bin/plackup" 17 | NAME="libremailer" 18 | SOCK="/var/tmp/._dancer_$NAME.sock" 19 | DESC="$NAME web app" 20 | USER="www-data" 21 | WORKERS="2" 22 | OPTS="$PERL $PLACKUP -E production -s Starman --user=$USER --workers=$WORKERS -l $SOCK -a $DAEMON" 23 | 24 | # Start the service 25 | start() { 26 | echo -n "Starting $DESC: " 27 | cd $APP_HOME 28 | $OPTS &> /dev/null & 29 | echo -n "done." 30 | echo 31 | } 32 | 33 | # Restart the service 34 | stop() { 35 | echo -n "Stopping $DESC: " 36 | /sbin/fuser -k $SOCK > /dev/null 2>&1 37 | rm -f $SOCK > /dev/null 2>&1 38 | echo -n "done." 39 | echo 40 | } 41 | 42 | ### main logic ### 43 | case "$1" in 44 | start) 45 | start 46 | ;; 47 | stop) 48 | stop 49 | ;; 50 | status) 51 | /sbin/fuser -v -u $SOCK 52 | ;; 53 | restart|reload|condrestart) 54 | stop 55 | start 56 | ;; 57 | *) 58 | echo $"Usage: $0 {start|stop|restart|reload|status}" 59 | exit 1 60 | esac 61 | 62 | exit 0 63 | -------------------------------------------------------------------------------- /bin/worker.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use strict; 4 | use warnings; 5 | use FindBin; 6 | use Cwd qw( realpath ); 7 | use Dancer ':script'; 8 | 9 | my $appdir = realpath( "$FindBin::Bin/.."); 10 | 11 | Dancer::Config::setting( 'appdir', $appdir ); 12 | config->{environment} = 'production'; 13 | Dancer::Config::load(); 14 | 15 | use LibreMailer::Worker; 16 | 17 | my $worker = LibreMailer::Worker->new(); 18 | 19 | $worker->clean_lists; 20 | $worker->process_campaigns; 21 | $worker->process_bounces; 22 | -------------------------------------------------------------------------------- /config.yml: -------------------------------------------------------------------------------- 1 | # EDIT: THIS IS REALLY IMPORTANT, session cookie key must be set with a unqiue random key 2 | session_cookie_key: "" 3 | 4 | # Session expires in seconds 5 | session_expires: 28800 6 | 7 | # EDIT: THIS IS REALLY IMPORTANT, url key must be set with a unqiue random key 8 | url_key: "" 9 | 10 | # EDIT: The timezone you wish the app to use 11 | timezone: "Australia/Sydney" 12 | 13 | # EDIT: The smtp server used for sending mail 14 | smtp_server: ':' 15 | 16 | # EDIT: The base url of the application. Required by the cron job sending out mail. 17 | base_url: '' 18 | 19 | # EDIT: Reply address used for collecting bounce messages. Address Must match bounce mailbox details below for 20 | # bounce message processing to work. 21 | email_from: '' 22 | 23 | # EDIT: Secure pop3 account details to login into email_from address 24 | # WARNING: This must be a dedicated mailbox to bounce messages as all messages will be deleted after processing. 25 | process_bounce_messages: '' 26 | pop3_bounce_ssl_host: ':' 27 | pop3_bounce_username: '' 28 | pop3_bounce_password: '' 29 | 30 | plugins: 31 | 32 | # EDIT: Database settings 33 | Database: 34 | driver: 'mysql' 35 | database: 'libremailer' 36 | host: 'localhost' 37 | port: '3306' 38 | username: '' 39 | password: '' 40 | connection_check_threshold: 10 41 | dbi_params: 42 | RaiseError: 1 43 | AutoCommit: 1 44 | log_queries: 1 45 | 46 | Auth::Extensible: 47 | no_default_pages: 1 48 | no_login_handler: 1 49 | realms: 50 | users: 51 | provider: 'Database' 52 | 53 | # SETTINGS BELOW THIS POINT DO NOT REQUIRE MODIFICATION. 54 | Passphrase: 55 | default: bcrypt 56 | bcrypt: 57 | cost: 20 58 | 59 | appname: 'LibreMailer' 60 | serializer: 'JSON' 61 | session: 'cookie' 62 | charset: 'UTF-8' 63 | layout: 'main' 64 | template: 'template_toolkit' 65 | engines: 66 | template_toolkit: 67 | encoding: 'utf8' 68 | start_tag: '[%' 69 | end_tag: '%]' 70 | -------------------------------------------------------------------------------- /environments/development.yml: -------------------------------------------------------------------------------- 1 | # configuration file for development environment 2 | 3 | # the logger engine to use 4 | # console: log messages to STDOUT (your console where you started the 5 | # application server) 6 | # file: log message to a file in log/ 7 | logger: "console" 8 | 9 | # the log level for this environment 10 | # core is the lowest, it shows Dancer's core log messages as well as yours 11 | # (debug, info, warning and error) 12 | log: "core" 13 | 14 | # should Dancer consider warnings as critical errors? 15 | warnings: 1 16 | 17 | # should Dancer show a stacktrace when an error is caught? 18 | show_errors: 1 19 | 20 | # auto_reload is a development and experimental feature 21 | # you should enable it by yourself if you want it 22 | # Module::Refresh is needed 23 | # 24 | # Be aware it's unstable and may cause a memory leak. 25 | # DO NOT EVER USE THIS FEATURE IN PRODUCTION 26 | # OR TINY KITTENS SHALL DIE WITH LOTS OF SUFFERING 27 | auto_reload: 0 28 | -------------------------------------------------------------------------------- /environments/production.yml: -------------------------------------------------------------------------------- 1 | # configuration file for production environment 2 | 3 | # only log warning and error messages 4 | log: "warning" 5 | 6 | # log message to a file in logs/ 7 | logger: "file" 8 | 9 | # don't consider warnings critical 10 | warnings: 0 11 | 12 | # hide errors 13 | show_errors: 0 14 | 15 | # cache route resolution for maximum performance 16 | route_cache: 1 17 | 18 | -------------------------------------------------------------------------------- /lib/LibreMailer/Contacts.pm: -------------------------------------------------------------------------------- 1 | package LibreMailer::Contacts; 2 | 3 | use Dancer ':syntax'; 4 | use Dancer::Plugin::Database; 5 | use Dancer::Plugin::SimpleCRUD; 6 | use Dancer::Plugin::Auth::Extensible; 7 | use Dancer::Plugin::Passphrase; 8 | use Dancer::Session::Cookie; 9 | use Dancer::Plugin::REST; 10 | use Dancer::Plugin::FlashMessage; 11 | use Dancer::FileUtils qw(dirname path read_file_content); 12 | use Email::Valid; 13 | use Text::CSV; 14 | use Data::Dumper; 15 | 16 | simple_crud( 17 | record_title => 'Contact', 18 | prefix => '/contacts', 19 | db_table => 'contacts', 20 | labels => { 21 | list_id => 'Contact List', 22 | email => 'Email Address', 23 | format => 'Email Format', 24 | confirmation => 'Confirmation Status', 25 | firstname => 'First Name', 26 | lastname => 'Last Name', 27 | }, 28 | input_types => { 29 | list_id => 'select', 30 | firstname => 'text', 31 | lastname => 'text', 32 | format => 'select', 33 | confirmation => 'select', 34 | status => 'select', 35 | }, 36 | required => [ qw( list_id email format confirmation status firstname lastname ) ], 37 | key_column => 'id', 38 | editable_columns => [ qw( list_id email format confirmation status firstname lastname ) ], 39 | display_columns => [ qw( list_id email format confirmation status firstname lastname ) ], 40 | deleteable => 1, 41 | editable => 1, 42 | sortable => 1, 43 | paginate => 100, 44 | template => 'contacts.tt', 45 | query_auto_focus => 0, 46 | downloadable => 1, 47 | foreign_keys => { 48 | list_id => { 49 | table => 'lists', 50 | key_column => 'id', 51 | label_column => 'name', 52 | }, 53 | }, 54 | ); 55 | 56 | true; 57 | 58 | __END__ 59 | 60 | =pod 61 | 62 | =head1 NAME 63 | 64 | LibreMailer::Contacts 65 | 66 | =head1 DESCRIPTION 67 | 68 | Contact management 69 | 70 | =head1 AUTHOR 71 | 72 | Sarah Fuller, C<< >> 73 | 74 | =head1 LICENSE AND COPYRIGHT 75 | 76 | This file is part of LibreMailer 77 | 78 | LibreMailer is free software: you can redistribute it and/or modify 79 | it under the terms of the GNU General Public License as published by 80 | the Free Software Foundation, either version 3 of the License, or 81 | (at your option) any later version. 82 | 83 | LibreMailer is distributed in the hope that it will be useful, 84 | but WITHOUT ANY WARRANTY; without even the implied warranty of 85 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 86 | GNU General Public License for more details. 87 | 88 | You should have received a copy of the GNU General Public License 89 | along with LibreMailer. If not, see . 90 | 91 | =cut 92 | 93 | -------------------------------------------------------------------------------- /lib/LibreMailer/DateTime.pm: -------------------------------------------------------------------------------- 1 | package LibreMailer::DateTime; 2 | 3 | use Moo; 4 | use Dancer qw(:syntax !before !after); 5 | use DateTime; 6 | use DateTime::Format::MySQL; 7 | use Data::Dumper; 8 | 9 | our $VERSION = '0.1'; 10 | 11 | has timezone => ( is => 'ro', default => sub { config->{timezone} } ); 12 | 13 | sub current_datetime 14 | { 15 | # Load current DateTime 16 | my $self = shift; 17 | my $dt = DateTime->now; 18 | 19 | $dt->set_time_zone( $self->timezone ); 20 | 21 | return $dt; 22 | } 23 | 24 | sub sql_current_datetime 25 | { 26 | # Load current DateTime in SQL datetime 27 | my $self = shift; 28 | my $dt = DateTime->now; 29 | 30 | $dt->set_time_zone( $self->timezone ); 31 | 32 | return DateTime::Format::MySQL->format_datetime( $dt ); 33 | } 34 | 35 | sub convert_sqlt_to_dt 36 | { 37 | # Convert SQL datetime to DateTime 38 | my $self = shift; 39 | my $dt = shift; 40 | 41 | return DateTime::Format::MySQL->parse_datetime( $dt ); 42 | } 43 | 44 | sub convert_dt_to_sqlt 45 | { 46 | # Convert DateTime to SQL datetime 47 | my $self = shift; 48 | my $dt = shift; 49 | 50 | $dt->set_time_zone( $self->timezone ); 51 | 52 | return DateTime::Format::MySQL->format_datetime( $dt ); 53 | } 54 | 55 | sub check_schedule 56 | { 57 | # Convert DateTime to SQL datetime 58 | my $self = shift; 59 | my $schedule_dt = $self->convert_sqlt_to_dt( shift ); 60 | my $current_dt = DateTime->now; 61 | 62 | $current_dt->set_time_zone( $self->timezone ); 63 | 64 | my $compare = DateTime->compare( $current_dt, $schedule_dt ); 65 | 66 | return ( $compare >= 0 ) ? 1 : 0; 67 | } 68 | 69 | 1; 70 | 71 | __END__ 72 | 73 | =pod 74 | 75 | =head1 NAME 76 | 77 | LibreMailer::DateTime 78 | 79 | =head1 DESCRIPTION 80 | 81 | date stuff cos I'm lazy 82 | 83 | =head1 AUTHOR 84 | 85 | Sarah Fuller, C<< >> 86 | 87 | =head1 LICENSE AND COPYRIGHT 88 | 89 | This file is part of LibreMailer 90 | 91 | LibreMailer is free software: you can redistribute it and/or modify 92 | it under the terms of the GNU General Public License as published by 93 | the Free Software Foundation, either version 3 of the License, or 94 | (at your option) any later version. 95 | 96 | LibreMailer is distributed in the hope that it will be useful, 97 | but WITHOUT ANY WARRANTY; without even the implied warranty of 98 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 99 | GNU General Public License for more details. 100 | 101 | You should have received a copy of the GNU General Public License 102 | along with LibreMailer. If not, see . 103 | 104 | =cut 105 | 106 | -------------------------------------------------------------------------------- /lib/LibreMailer/EncodeSafeURL.pm: -------------------------------------------------------------------------------- 1 | package LibreMailer::EncodeSafeURL; 2 | 3 | use Moo; 4 | use Dancer qw(:syntax !before !after); 5 | use Dancer::Plugin::Database; 6 | use MIME::Base64::URLSafe; 7 | use Crypt::CBC; 8 | use Crypt::Blowfish; 9 | use Try::Tiny; 10 | use Data::Dumper; 11 | 12 | our $VERSION = '0.1'; 13 | 14 | sub encrypt_sting 15 | { 16 | # Encrypt string for sending 17 | my $self = shift; 18 | my $string = shift; 19 | my $cipher = Crypt::CBC->new( 20 | -key => config->{url_key}, 21 | -cipher => 'Blowfish', 22 | -padding => 'space', 23 | -add_header => 1 24 | ); 25 | 26 | my $enc = $cipher->encrypt( $string ); 27 | 28 | return urlsafe_b64encode( $enc ); 29 | } 30 | 31 | sub decrypt_string 32 | { 33 | # Decrypt string for processing 34 | my $self = shift; 35 | my $string = urlsafe_b64decode( shift ); 36 | my $dec; 37 | my $cipher = Crypt::CBC->new( 38 | -key => config->{url_key}, 39 | -cipher => 'Blowfish', 40 | -padding => 'space', 41 | -add_header => 1 42 | ); 43 | 44 | try{ $dec = $cipher->decrypt( $string ); }; 45 | 46 | return $dec; 47 | } 48 | 49 | 1; 50 | 51 | __END__ 52 | 53 | =pod 54 | 55 | =head1 NAME 56 | 57 | LibreMailer::EncodeSafeURL 58 | 59 | =head1 DESCRIPTION 60 | 61 | url encoding and encryption 62 | 63 | =head1 AUTHOR 64 | 65 | Sarah Fuller, C<< >> 66 | 67 | =head1 LICENSE AND COPYRIGHT 68 | 69 | This file is part of LibreMailer 70 | 71 | LibreMailer is free software: you can redistribute it and/or modify 72 | it under the terms of the GNU General Public License as published by 73 | the Free Software Foundation, either version 3 of the License, or 74 | (at your option) any later version. 75 | 76 | LibreMailer is distributed in the hope that it will be useful, 77 | but WITHOUT ANY WARRANTY; without even the implied warranty of 78 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 79 | GNU General Public License for more details. 80 | 81 | You should have received a copy of the GNU General Public License 82 | along with LibreMailer. If not, see . 83 | 84 | =cut 85 | -------------------------------------------------------------------------------- /lib/LibreMailer/RestClient.pm: -------------------------------------------------------------------------------- 1 | package LibreMailer::RestClient; 2 | 3 | # I just use this for testing. Feel free to ignore it. 4 | 5 | use Moo; 6 | use REST::Client; 7 | use LWP::UserAgent; 8 | use HTTP::Cookies; 9 | use Data::Dumper; 10 | 11 | our $VERSION = '1.0'; 12 | 13 | has host => ( is => 'rw', default => sub { 'http://localhost:3000'; }, ); 14 | has cookie_file => ( is => 'rw', default => sub { return '/tmp/.libre_lwp_cookies.dat'; }, ); 15 | has cookie_jar => ( is => 'rw', default => \&_set_cookie_jar, ); 16 | has lwp_ua => ( is => 'rw', default => \&_set_lwp_ua, ); 17 | has client => ( is => 'rw', default => \&_set_rest_client, lazy => 1, ); 18 | has show_progress => ( is => 'rw', default => sub { 1; }, ); 19 | 20 | sub _set_cookie_jar 21 | { 22 | my $self = shift; 23 | 24 | return HTTP::Cookies->new( file => $self->cookie_file, autosave => 1, ); 25 | } 26 | 27 | sub _set_lwp_ua 28 | { 29 | my $self = shift; 30 | my $ua = LWP::UserAgent->new( 31 | cookie_jar => $self->cookie_jar, 32 | requests_redirectable => [ 'GET', 'HEAD', 'POST', 'PUT', 'DELETE' ] 33 | ); 34 | 35 | $ua->show_progress( $self->show_progress ); 36 | 37 | return $ua; 38 | } 39 | 40 | sub _set_rest_client 41 | { 42 | my $self = shift; 43 | 44 | return REST::Client->new( { useragent => $self->lwp_ua } ); 45 | } 46 | 47 | sub request 48 | { 49 | my $self = shift; 50 | my $type = shift; 51 | my $url = shift; 52 | my $data = shift; 53 | my $c_type = shift; 54 | 55 | $c_type = 56 | ( !$c_type && $url && $url =~ m/json$/ ) 57 | ? 'application/json' 58 | : 'text/html'; 59 | 60 | $self->client->request( $type, $self->host . $url, 61 | $data, { "Content-type" => $c_type } ); 62 | 63 | return ( $self->client->responseCode(), $self->client->responseContent() ); 64 | } 65 | 66 | 1; 67 | 68 | __END__ 69 | 70 | =pod 71 | 72 | =head1 NAME 73 | 74 | LibreMailer::RestClient 75 | 76 | =head1 DESCRIPTION 77 | 78 | Just a rest client helper for testing. 79 | Not part of app. 80 | 81 | =head1 AUTHOR 82 | 83 | Sarah Fuller, C<< >> 84 | 85 | =head1 LICENSE AND COPYRIGHT 86 | 87 | This file is part of LibreMailer. 88 | 89 | LibreMailer is free software: you can redistribute it and/or modify 90 | it under the terms of the GNU General Public License as published by 91 | the Free Software Foundation, either version 3 of the License, or 92 | (at your option) any later version. 93 | 94 | LibreMailer is distributed in the hope that it will be useful, 95 | but WITHOUT ANY WARRANTY; without even the implied warranty of 96 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 97 | GNU General Public License for more details. 98 | 99 | You should have received a copy of the GNU General Public License 100 | along with LibreMailer. If not, see . 101 | 102 | =cut 103 | -------------------------------------------------------------------------------- /lib/LibreMailer/Roles.pm: -------------------------------------------------------------------------------- 1 | package LibreMailer::Roles; 2 | 3 | use Dancer ':syntax'; 4 | use Dancer::Plugin::Database; 5 | use Dancer::Plugin::SimpleCRUD; 6 | use Dancer::Plugin::Auth::Extensible; 7 | use Dancer::Plugin::Passphrase; 8 | use Dancer::Session::Cookie; 9 | use Dancer::Plugin::REST; 10 | use Dancer::Plugin::FlashMessage; 11 | use Dancer::FileUtils qw(dirname path read_file_content); 12 | use Email::Valid; 13 | use Text::CSV; 14 | use Data::Dumper; 15 | 16 | simple_crud( 17 | record_title => 'Role', 18 | prefix => '/roles', 19 | db_table => 'user_roles', 20 | labels => { 21 | user_id => 'Username', 22 | role_id => 'Role', 23 | 24 | }, 25 | input_types => { 26 | role_id => 'select', 27 | user_id => 'select', 28 | }, 29 | required => [ qw( role_id user_id ) ], 30 | key_column => 'id', 31 | editable_columns => [ qw( role_id user_id ) ], 32 | display_columns => [ qw( role_id user_id ) ], 33 | deleteable => 1, 34 | editable => 1, 35 | sortable => 1, 36 | paginate => 100, 37 | template => 'roles.tt', 38 | query_auto_focus => 0, 39 | downloadable => 1, 40 | foreign_keys => { 41 | role_id => { 42 | table => 'roles', 43 | key_column => 'id', 44 | label_column => 'role', 45 | }, 46 | user_id => { 47 | table => 'users', 48 | key_column => 'id', 49 | label_column => 'username', 50 | }, 51 | }, 52 | auth => { 53 | view => { 54 | require_login => 1, 55 | }, 56 | edit => { 57 | require_role => 'Administrator', 58 | }, 59 | }, 60 | ); 61 | 62 | true; 63 | 64 | __END__ 65 | 66 | =pod 67 | 68 | =head1 NAME 69 | 70 | LibreMailer::Roles 71 | 72 | =head1 DESCRIPTION 73 | 74 | Does anyone even read this stuff? 75 | 76 | =head1 AUTHOR 77 | 78 | Sarah Fuller, C<< >> 79 | 80 | =head1 LICENSE AND COPYRIGHT 81 | 82 | This file is part of LibreMailer 83 | 84 | LibreMailer is free software: you can redistribute it and/or modify 85 | it under the terms of the GNU General Public License as published by 86 | the Free Software Foundation, either version 3 of the License, or 87 | (at your option) any later version. 88 | 89 | LibreMailer is distributed in the hope that it will be useful, 90 | but WITHOUT ANY WARRANTY; without even the implied warranty of 91 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 92 | GNU General Public License for more details. 93 | 94 | You should have received a copy of the GNU General Public License 95 | along with LibreMailer. If not, see . 96 | 97 | =cut 98 | -------------------------------------------------------------------------------- /lib/LibreMailer/Users.pm: -------------------------------------------------------------------------------- 1 | package LibreMailer::Users; 2 | 3 | use Dancer ':syntax'; 4 | use Dancer::Plugin::Database; 5 | use Dancer::Plugin::SimpleCRUD; 6 | use Dancer::Plugin::Auth::Extensible; 7 | use Dancer::Plugin::Passphrase; 8 | use Dancer::Session::Cookie; 9 | use Dancer::Plugin::REST; 10 | use Dancer::Plugin::FlashMessage; 11 | use Dancer::FileUtils qw(dirname path read_file_content); 12 | use Email::Valid; 13 | use Text::CSV; 14 | use Data::Dumper; 15 | 16 | simple_crud( 17 | record_title => 'User', 18 | prefix => '/users', 19 | db_table => 'users', 20 | labels => { 21 | username => 'Username', 22 | password => 'Password', 23 | firstname => 'First Name', 24 | lastname => 'Last Name', 25 | email => 'Email Address', 26 | }, 27 | validation => { 28 | id => qr/\d+/, 29 | }, 30 | input_types => { 31 | username => 'text', 32 | firstname => 'text', 33 | lastname => 'text', 34 | password => 'password', 35 | email => 'text', 36 | }, 37 | required => [ qw( username password firstname lastname email ) ], 38 | key_column => 'id', 39 | editable_columns => [ qw( username password firstname lastname email ) ], 40 | display_columns => [ qw( username firstname lastname email ) ], 41 | deleteable => 1, 42 | editable => 1, 43 | sortable => 1, 44 | paginate => 100, 45 | template => 'users.tt', 46 | query_auto_focus => 0, 47 | downloadable => 1, 48 | custom_columns => { 49 | 'Roles' => { 50 | raw_column => "id", 51 | transform => sub { 52 | my $id = shift; 53 | my $db = database; 54 | my @user_roles = $db->quick_select( 'user_roles', { user_id => $id } ); 55 | my @roles; 56 | 57 | map { my $role = $db->quick_select( 'roles', { id => $_->{role_id} } ); push( @roles, $role ); } @user_roles; 58 | 59 | my $roles; 60 | 61 | map { $roles .= '' . $_->{role} . ', ' } @roles; 62 | 63 | $roles = 'Add a Role' if ( ! $roles ); 64 | 65 | return $roles; 66 | }, 67 | }, 68 | }, 69 | auth => { 70 | view => { 71 | require_login => 1, 72 | }, 73 | edit => { 74 | require_role => 'Administrator', 75 | }, 76 | }, 77 | ); 78 | 79 | true; 80 | 81 | __END__ 82 | 83 | =pod 84 | 85 | =head1 NAME 86 | 87 | LibreMailer::Users 88 | 89 | =head1 DESCRIPTION 90 | 91 | user management 92 | 93 | =head1 AUTHOR 94 | 95 | Sarah Fuller, C<< >> 96 | 97 | =head1 LICENSE AND COPYRIGHT 98 | 99 | This file is part of LibreMailer 100 | 101 | LibreMailer is free software: you can redistribute it and/or modify 102 | it under the terms of the GNU General Public License as published by 103 | the Free Software Foundation, either version 3 of the License, or 104 | (at your option) any later version. 105 | 106 | LibreMailer is distributed in the hope that it will be useful, 107 | but WITHOUT ANY WARRANTY; without even the implied warranty of 108 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 109 | GNU General Public License for more details. 110 | 111 | You should have received a copy of the GNU General Public License 112 | along with LibreMailer. If not, see . 113 | 114 | =cut 115 | 116 | -------------------------------------------------------------------------------- /logs/production.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/logs/production.log -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Error 404 6 | 7 | 8 | 9 | 10 |

Error 404

11 |
12 |

Page Not Found

Sorry, this is the void.

13 |
14 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Error 500 6 | 7 | 8 | 9 | 10 |

Error 500

11 |
12 |

Internal Server Error

Wooops, something went wrong

13 |
14 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /public/Chart.js-master/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | 4 | node_modules/* 5 | custom/* 6 | 7 | docs/index.md 8 | -------------------------------------------------------------------------------- /public/Chart.js-master/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2014 Nick Downie 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /public/Chart.js-master/README.md: -------------------------------------------------------------------------------- 1 | # Chart.js 2 | 3 | *Simple HTML5 Charts using the canvas element* [chartjs.org](http://www.chartjs.org) 4 | 5 | ## Documentation 6 | 7 | You can find documentation at [chartjs.org/docs](http://www.chartjs.org/docs). The markdown files that build the site are available under `/docs`. Please note - in some of the json examples of configuration you might notice some liquid tags - this is just for the generating the site html, please disregard. 8 | 9 | ## License 10 | 11 | Chart.js is available under the [MIT license](http://opensource.org/licenses/MIT). 12 | 13 | ## Bugs & issues 14 | 15 | When reporting bugs or issues, if you could include a link to a simple [jsbin](http://jsbin.com) or similar demonstrating the issue, that'd be really helpful. 16 | 17 | 18 | ## Contributing 19 | New contributions to the library are welcome, just a couple of guidelines: 20 | 21 | - Tabs for indentation, not spaces please. 22 | - Please ensure you're changing the individual files in `/src`, not the concatenated output in the `Chart.js` file in the root of the repo. 23 | - Please check that your code will pass `jshint` code standards, `gulp jshint` will run this for you. 24 | - Please keep pull requests concise, and document new functionality in the relevant `.md` file. 25 | - Consider whether your changes are useful for all users, or if creating a Chart.js extension would be more appropriate. 26 | - Please avoid committing in the build Chart.js & Chart.min.js file, as it causes conflicts when merging. 27 | -------------------------------------------------------------------------------- /public/Chart.js-master/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Chart.js", 3 | "version": "1.0.1-beta.4", 4 | "description": "Simple HTML5 Charts using the canvas element", 5 | "homepage": "https://github.com/nnnick/Chart.js", 6 | "author": "nnnick", 7 | "main": [ 8 | "Chart.min.js" 9 | ], 10 | "dependencies": {} 11 | } -------------------------------------------------------------------------------- /public/Chart.js-master/docs/02-Bar-Chart.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Bar Chart 3 | anchor: bar-chart 4 | --- 5 | 6 | ### Introduction 7 | A bar chart is a way of showing data as bars. 8 | 9 | It is sometimes used to show trend data, and the comparison of multiple data sets side by side. 10 | 11 |
12 | 13 |
14 | 15 | ### Example usage 16 | ```javascript 17 | var myBarChart = new Chart(ctx).Bar(data, options); 18 | ``` 19 | 20 | ### Data structure 21 | 22 | ```javascript 23 | var data = { 24 | labels: ["January", "February", "March", "April", "May", "June", "July"], 25 | datasets: [ 26 | { 27 | label: "My First dataset", 28 | fillColor: "rgba(220,220,220,0.5)", 29 | strokeColor: "rgba(220,220,220,0.8)", 30 | highlightFill: "rgba(220,220,220,0.75)", 31 | highlightStroke: "rgba(220,220,220,1)", 32 | data: [65, 59, 80, 81, 56, 55, 40] 33 | }, 34 | { 35 | label: "My Second dataset", 36 | fillColor: "rgba(151,187,205,0.5)", 37 | strokeColor: "rgba(151,187,205,0.8)", 38 | highlightFill: "rgba(151,187,205,0.75)", 39 | highlightStroke: "rgba(151,187,205,1)", 40 | data: [28, 48, 40, 19, 86, 27, 90] 41 | } 42 | ] 43 | }; 44 | ``` 45 | The bar chart has the a very similar data structure to the line chart, and has an array of datasets, each with colours and an array of data. Again, colours are in CSS format. 46 | We have an array of labels too for display. In the example, we are showing the same data as the previous line chart example. 47 | 48 | The label key on each dataset is optional, and can be used when generating a scale for the chart. 49 | 50 | ### Chart Options 51 | 52 | These are the customisation options specific to Bar charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart. 53 | 54 | ```javascript 55 | { 56 | //Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value 57 | scaleBeginAtZero : true, 58 | 59 | //Boolean - Whether grid lines are shown across the chart 60 | scaleShowGridLines : true, 61 | 62 | //String - Colour of the grid lines 63 | scaleGridLineColor : "rgba(0,0,0,.05)", 64 | 65 | //Number - Width of the grid lines 66 | scaleGridLineWidth : 1, 67 | 68 | //Boolean - If there is a stroke on each bar 69 | barShowStroke : true, 70 | 71 | //Number - Pixel width of the bar stroke 72 | barStrokeWidth : 2, 73 | 74 | //Number - Spacing between each of the X value sets 75 | barValueSpacing : 5, 76 | 77 | //Number - Spacing between data sets within X values 78 | barDatasetSpacing : 1, 79 | {% raw %} 80 | //String - A legend template 81 | legendTemplate : "
    -legend\"><% for (var i=0; i
  • \"><%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>
" 82 | {% endraw %} 83 | } 84 | ``` 85 | 86 | You can override these for your `Chart` instance by passing a second argument into the `Bar` method as an object with the keys you want to override. 87 | 88 | For example, we could have a bar chart without a stroke on each bar by doing the following: 89 | 90 | ```javascript 91 | new Chart(ctx).Bar(data, { 92 | barShowStroke: false 93 | }); 94 | // This will create a chart with all of the default options, merged from the global config, 95 | // and the Bar chart defaults but this particular instance will have `barShowStroke` set to false. 96 | ``` 97 | 98 | We can also change these defaults values for each Bar type that is created, this object is available at `Chart.defaults.Bar`. 99 | 100 | ### Prototype methods 101 | 102 | #### .getBarsAtEvent( event ) 103 | 104 | Calling `getBarsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the bar elements that are at that the same position of that event. 105 | 106 | ```javascript 107 | canvas.onclick = function(evt){ 108 | var activeBars = myBarChart.getBarsAtEvent(evt); 109 | // => activeBars is an array of bars on the canvas that are at the same position as the click event. 110 | }; 111 | ``` 112 | 113 | This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application. 114 | 115 | #### .update( ) 116 | 117 | Calling `update()` on your Chart instance will re-render the chart with any updated values, allowing you to edit the value of multiple existing points, then render those in one animated render loop. 118 | 119 | ```javascript 120 | myBarChart.datasets[0].bars[2].value = 50; 121 | // Would update the first dataset's value of 'March' to be 50 122 | myBarChart.update(); 123 | // Calling update now animates the position of March from 90 to 50. 124 | ``` 125 | 126 | #### .addData( valuesArray, label ) 127 | 128 | Calling `addData(valuesArray, label)` on your Chart instance passing an array of values for each dataset, along with a label for those bars. 129 | 130 | ```javascript 131 | // The values array passed into addData should be one for each dataset in the chart 132 | myBarChart.addData([40, 60], "August"); 133 | // The new data will now animate at the end of the chart. 134 | ``` 135 | 136 | #### .removeData( ) 137 | 138 | Calling `removeData()` on your Chart instance will remove the first value for all datasets on the chart. 139 | 140 | ```javascript 141 | myBarChart.removeData(); 142 | // The chart will now animate and remove the first bar 143 | ``` -------------------------------------------------------------------------------- /public/Chart.js-master/docs/07-Notes.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Notes 3 | anchor: notes 4 | --- 5 | 6 | ### Browser support 7 | Browser support for the canvas element is available in all modern & major mobile browsers (caniuse.com/canvas). 8 | 9 | For IE8 & below, I would recommend using the polyfill ExplorerCanvas - available at https://code.google.com/p/explorercanvas/. It falls back to Internet explorer's format VML when canvas support is not available. Example use: 10 | 11 | ```html 12 | 13 | 16 | 17 | ``` 18 | 19 | Usually I would recommend feature detection to choose whether or not to load a polyfill, rather than IE conditional comments, however in this case, VML is a Microsoft proprietary format, so it will only work in IE. 20 | 21 | Some important points to note in my experience using ExplorerCanvas as a fallback. 22 | 23 | - Initialise charts on load rather than DOMContentReady when using the library, as sometimes a race condition will occur, and it will result in an error when trying to get the 2d context of a canvas. 24 | - New VML DOM elements are being created for each animation frame and there is no hardware acceleration. As a result animation is usually slow and jerky, with flashing text. It is a good idea to dynamically turn off animation based on canvas support. I recommend using the excellent Modernizr to do this. 25 | - When declaring fonts, the library explorercanvas requires the font name to be in single quotes inside the string. For example, instead of your scaleFontFamily property being simply "Arial", explorercanvas support, use "'Arial'" instead. Chart.js does this for default values. 26 | 27 | ### Bugs & issues 28 | 29 | Please report these on the GitHub page - at github.com/nnnick/Chart.js. If you could include a link to a simple jsbin or similar to demonstrate the issue, that'd be really helpful. 30 | 31 | 32 | ### Contributing 33 | New contributions to the library are welcome, just a couple of guidelines: 34 | 35 | - Tabs for indentation, not spaces please. 36 | - Please ensure you're changing the individual files in `/src`, not the concatenated output in the `Chart.js` file in the root of the repo. 37 | - Please check that your code will pass `jshint` code standards, `gulp jshint` will run this for you. 38 | - Please keep pull requests concise, and document new functionality in the relevant `.md` file. 39 | - Consider whether your changes are useful for all users, or if creating a Chart.js extension would be more appropriate. 40 | 41 | ### License 42 | Chart.js is open source and available under the MIT license. -------------------------------------------------------------------------------- /public/Chart.js-master/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | concat = require('gulp-concat'), 3 | uglify = require('gulp-uglify'), 4 | util = require('gulp-util'), 5 | jshint = require('gulp-jshint'), 6 | size = require('gulp-size'), 7 | connect = require('gulp-connect'), 8 | replace = require('gulp-replace'), 9 | inquirer = require('inquirer'), 10 | semver = require('semver'), 11 | exec = require('child_process').exec, 12 | fs = require('fs'), 13 | package = require('./package.json'), 14 | bower = require('./bower.json'); 15 | 16 | var srcDir = './src/'; 17 | /* 18 | * Usage : gulp build --types=Bar,Line,Doughnut 19 | * Output: - A built Chart.js file with Core and types Bar, Line and Doughnut concatenated together 20 | * - A minified version of this code, in Chart.min.js 21 | */ 22 | 23 | gulp.task('build', function(){ 24 | 25 | // Default to all of the chart types, with Chart.Core first 26 | var srcFiles = [FileName('Core')], 27 | isCustom = !!(util.env.types), 28 | outputDir = (isCustom) ? 'custom' : '.'; 29 | if (isCustom){ 30 | util.env.types.split(',').forEach(function(type){ return srcFiles.push(FileName(type))}); 31 | } 32 | else{ 33 | // Seems gulp-concat remove duplicates - nice! 34 | // So we can use this to sort out dependency order - aka include Core first! 35 | srcFiles.push(srcDir+'*'); 36 | } 37 | 38 | return gulp.src(srcFiles) 39 | .pipe(concat('Chart.js')) 40 | .pipe(replace('{{ version }}', package.version)) 41 | .pipe(gulp.dest(outputDir)) 42 | .pipe(uglify({preserveComments:'some'})) 43 | .pipe(concat('Chart.min.js')) 44 | .pipe(gulp.dest(outputDir)); 45 | 46 | function FileName(moduleName){ 47 | return srcDir+'Chart.'+moduleName+'.js'; 48 | }; 49 | }); 50 | 51 | /* 52 | * Usage : gulp bump 53 | * Prompts: Version increment to bump 54 | * Output: - New version number written into package.json & bower.json 55 | */ 56 | 57 | gulp.task('bump', function(complete){ 58 | util.log('Current version:', util.colors.cyan(package.version)); 59 | var choices = ['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'].map(function(versionType){ 60 | return versionType + ' (v' + semver.inc(package.version, versionType) + ')'; 61 | }); 62 | inquirer.prompt({ 63 | type: 'list', 64 | name: 'version', 65 | message: 'What version update would you like?', 66 | choices: choices 67 | }, function(res){ 68 | var increment = res.version.split(' ')[0], 69 | newVersion = semver.inc(package.version, increment); 70 | 71 | // Set the new versions into the bower/package object 72 | package.version = newVersion; 73 | bower.version = newVersion; 74 | 75 | // Write these to their own files, then build the output 76 | fs.writeFileSync('package.json', JSON.stringify(package, null, 2)); 77 | fs.writeFileSync('bower.json', JSON.stringify(bower, null, 2)); 78 | 79 | complete(); 80 | }); 81 | }); 82 | 83 | gulp.task('release', ['build'], function(){ 84 | exec('git tag -a v' + package.version); 85 | }); 86 | 87 | gulp.task('jshint', function(){ 88 | return gulp.src(srcDir + '*.js') 89 | .pipe(jshint()) 90 | .pipe(jshint.reporter('default')); 91 | }); 92 | 93 | gulp.task('library-size', function(){ 94 | return gulp.src('Chart.min.js') 95 | .pipe(size({ 96 | gzip: true 97 | })); 98 | }); 99 | 100 | gulp.task('module-sizes', function(){ 101 | return gulp.src(srcDir + '*.js') 102 | .pipe(uglify({preserveComments:'some'})) 103 | .pipe(size({ 104 | showFiles: true, 105 | gzip: true 106 | })) 107 | }); 108 | 109 | gulp.task('watch', function(){ 110 | gulp.watch('./src/*', ['build']); 111 | }); 112 | 113 | gulp.task('test', ['jshint']); 114 | 115 | gulp.task('size', ['library-size', 'module-sizes']); 116 | 117 | gulp.task('default', ['build', 'watch']); 118 | 119 | gulp.task('server', function(){ 120 | connect.server({ 121 | port: 8000, 122 | }); 123 | }); 124 | 125 | // Convenience task for opening the project straight from the command line 126 | gulp.task('_open', function(){ 127 | exec('open http://localhost:8000'); 128 | exec('subl .'); 129 | }); 130 | 131 | gulp.task('dev', ['server', 'default']); 132 | -------------------------------------------------------------------------------- /public/Chart.js-master/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chart.js", 3 | "homepage": "http://www.chartjs.org", 4 | "description": "Simple HTML5 charts using the canvas element.", 5 | "version": "1.0.1-beta.4", 6 | "main": "Chart.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/nnnick/Chart.js.git" 10 | }, 11 | "dependences": {}, 12 | "devDependencies": { 13 | "gulp": "3.5.x", 14 | "gulp-concat": "~2.1.x", 15 | "gulp-connect": "~2.0.5", 16 | "gulp-jshint": "~1.5.1", 17 | "gulp-replace": "^0.4.0", 18 | "gulp-size": "~0.4.0", 19 | "gulp-uglify": "~0.2.x", 20 | "gulp-util": "~2.2.x", 21 | "inquirer": "^0.5.1", 22 | "semver": "^3.0.1" 23 | } 24 | } -------------------------------------------------------------------------------- /public/Chart.js-master/samples/bar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bar Chart 5 | 6 | 7 | 8 |
9 | 10 |
11 | 12 | 13 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /public/Chart.js-master/samples/doughnut.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Doughnut Chart 5 | 6 | 15 | 16 | 17 |
18 | 19 |
20 | 21 | 22 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /public/Chart.js-master/samples/line.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Line Chart 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
13 | 14 | 15 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /public/Chart.js-master/samples/pie.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pie Chart 5 | 6 | 7 | 8 |
9 | 10 |
11 | 12 | 13 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /public/Chart.js-master/samples/polar-area.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Polar Area Chart 5 | 6 | 7 | 8 |
9 | 10 |
11 | 12 | 13 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /public/Chart.js-master/samples/radar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Radar Chart 5 | 6 | 7 | 11 | 12 | 13 |
14 | 15 |
16 | 17 | 18 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /public/bootstrap-3.1.1-dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/bootstrap-3.1.1-dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /public/bootstrap-3.1.1-dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/bootstrap-3.1.1-dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /public/bootstrap-3.1.1-dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/bootstrap-3.1.1-dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /public/css/bootstrap-select.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-select v1.5.4 3 | * http://silviomoreto.github.io/bootstrap-select/ 4 | * 5 | * Copyright 2013 bootstrap-select 6 | * Licensed under the MIT license 7 | */.bootstrap-select.btn-group:not(.input-group-btn),.bootstrap-select.btn-group[class*="span"]{float:none;display:inline-block;margin-bottom:10px;margin-left:0}.form-search .bootstrap-select.btn-group,.form-inline .bootstrap-select.btn-group,.form-horizontal .bootstrap-select.btn-group{margin-bottom:0}.bootstrap-select.form-control{margin-bottom:0;padding:0;border:0}.bootstrap-select.btn-group.pull-right,.bootstrap-select.btn-group[class*="span"].pull-right,.row-fluid .bootstrap-select.btn-group[class*="span"].pull-right{float:right}.input-append .bootstrap-select.btn-group{margin-left:-1px}.input-prepend .bootstrap-select.btn-group{margin-right:-1px}.bootstrap-select:not([class*="span"]):not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn){width:220px}.bootstrap-select{width:220px\0}.bootstrap-select.form-control:not([class*="span"]){width:100%}.bootstrap-select>.btn{width:100%;padding-right:25px}.error .bootstrap-select .btn{border:1px solid #b94a48}.bootstrap-select.show-menu-arrow.open>.btn{z-index:2051}.bootstrap-select .btn:focus{outline:thin dotted #333 !important;outline:5px auto -webkit-focus-ring-color !important;outline-offset:-2px}.bootstrap-select.btn-group .btn .filter-option{display:inline-block;overflow:hidden;width:100%;float:left;text-align:left}.bootstrap-select.btn-group .btn .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.bootstrap-select.btn-group>.disabled,.bootstrap-select.btn-group .dropdown-menu li.disabled>a{cursor:not-allowed}.bootstrap-select.btn-group>.disabled:focus{outline:none !important}.bootstrap-select.btn-group[class*="span"] .btn{width:100%}.bootstrap-select.btn-group .dropdown-menu{min-width:100%;z-index:2000;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .dropdown-menu.inner{position:static;border:0;padding:0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.bootstrap-select.btn-group .dropdown-menu dt{display:block;padding:3px 20px;cursor:default}.bootstrap-select.btn-group .div-contain{overflow:hidden}.bootstrap-select.btn-group .dropdown-menu li{position:relative}.bootstrap-select.btn-group .dropdown-menu li>a.opt{position:relative;padding-left:35px}.bootstrap-select.btn-group .dropdown-menu li>a{cursor:pointer}.bootstrap-select.btn-group .dropdown-menu li>dt small{font-weight:normal}.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a i.check-mark{position:absolute;display:inline-block;right:15px;margin-top:2.5px}.bootstrap-select.btn-group .dropdown-menu li a i.check-mark{display:none}.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select.btn-group .dropdown-menu li small{padding-left:.5em}.bootstrap-select.btn-group .dropdown-menu li:not(.disabled)>a:hover small,.bootstrap-select.btn-group .dropdown-menu li:not(.disabled)>a:focus small,.bootstrap-select.btn-group .dropdown-menu li.active:not(.disabled)>a small{color:#64b1d8;color:rgba(255,255,255,0.4)}.bootstrap-select.btn-group .dropdown-menu li>dt small{font-weight:normal}.bootstrap-select.show-menu-arrow .dropdown-toggle:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #CCC;border-bottom-color:rgba(0,0,0,0.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid white;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before{bottom:auto;top:-3px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after{bottom:auto;top:-3px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:before,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:after{display:block}.bootstrap-select.btn-group .no-results{padding:3px;background:#f5f5f5;margin:0 5px}.bootstrap-select.btn-group .dropdown-menu .notify{position:absolute;bottom:5px;width:96%;margin:0 2%;min-height:26px;padding:3px 5px;background:#f5f5f5;border:1px solid #e3e3e3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);pointer-events:none;opacity:.9;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.mobile-device{position:absolute;top:0;left:0;display:block !important;width:100%;height:100% !important;opacity:0}.bootstrap-select.fit-width{width:auto !important}.bootstrap-select.btn-group.fit-width .btn .filter-option{position:static}.bootstrap-select.btn-group.fit-width .btn .caret{position:static;top:auto;margin-top:-1px}.control-group.error .bootstrap-select .dropdown-toggle{border-color:#b94a48}.bootstrap-select-searchbox,.bootstrap-select .bs-actionsbox{padding:4px 8px}.bootstrap-select .bs-actionsbox{float:left;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select-searchbox+.bs-actionsbox{padding:0 8px 4px}.bootstrap-select-searchbox input{margin-bottom:0}.bootstrap-select .bs-actionsbox .btn-group button{width:50%} -------------------------------------------------------------------------------- /public/css/error.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Lucida,sans-serif; 3 | } 4 | 5 | h1 { 6 | color: #AA0000; 7 | border-bottom: 1px solid #444; 8 | } 9 | 10 | h2 { color: #444; } 11 | 12 | pre { 13 | font-family: "lucida console","monaco","andale mono","bitstream vera sans mono","consolas",monospace; 14 | font-size: 12px; 15 | border-left: 2px solid #777; 16 | padding-left: 1em; 17 | } 18 | 19 | footer { 20 | font-size: 10px; 21 | } 22 | 23 | span.key { 24 | color: #449; 25 | font-weight: bold; 26 | width: 120px; 27 | display: inline; 28 | } 29 | 30 | span.value { 31 | color: #494; 32 | } 33 | 34 | /* these are for the message boxes */ 35 | 36 | pre.content { 37 | background-color: #eee; 38 | color: #000; 39 | padding: 1em; 40 | margin: 0; 41 | border: 1px solid #aaa; 42 | border-top: 0; 43 | margin-bottom: 1em; 44 | } 45 | 46 | div.title { 47 | font-family: "lucida console","monaco","andale mono","bitstream vera sans mono","consolas",monospace; 48 | font-size: 12px; 49 | background-color: #aaa; 50 | color: #444; 51 | font-weight: bold; 52 | padding: 3px; 53 | padding-left: 10px; 54 | } 55 | 56 | pre.content span.nu { 57 | color: #889; 58 | margin-right: 10px; 59 | } 60 | 61 | pre.error { 62 | background: #334; 63 | color: #ccd; 64 | padding: 1em; 65 | border-top: 1px solid #000; 66 | border-left: 1px solid #000; 67 | border-right: 1px solid #eee; 68 | border-bottom: 1px solid #eee; 69 | } 70 | 71 | -------------------------------------------------------------------------------- /public/css/style.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | margin: 0; 4 | margin-bottom: 25px; 5 | padding: 0; 6 | background-color: #ddd; 7 | background-image: url("/images/perldancer-bg.jpg"); 8 | background-repeat: no-repeat; 9 | background-position: top left; 10 | 11 | font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana"; 12 | font-size: 13px; 13 | color: #333; 14 | } 15 | 16 | h1 { 17 | font-size: 28px; 18 | color: #000; 19 | } 20 | 21 | a {color: #03c} 22 | a:hover { 23 | background-color: #03c; 24 | color: white; 25 | text-decoration: none; 26 | } 27 | 28 | #page { 29 | background-color: #ddd; 30 | width: 750px; 31 | margin: auto; 32 | margin-left: auto; 33 | padding-left: 0px; 34 | margin-right: auto; 35 | } 36 | 37 | #content { 38 | background-color: white; 39 | border: 3px solid #aaa; 40 | border-top: none; 41 | padding: 25px; 42 | width: 500px; 43 | } 44 | 45 | #sidebar { 46 | float: right; 47 | width: 175px; 48 | } 49 | 50 | #header, #about, #getting-started { 51 | padding-left: 75px; 52 | padding-right: 30px; 53 | } 54 | 55 | 56 | #header { 57 | background-image: url("/images/perldancer.jpg"); 58 | background-repeat: no-repeat; 59 | background-position: top left; 60 | height: 64px; 61 | } 62 | #header h1, #header h2 {margin: 0} 63 | #header h2 { 64 | color: #888; 65 | font-weight: normal; 66 | font-size: 16px; 67 | } 68 | 69 | #about h3 { 70 | margin: 0; 71 | margin-bottom: 10px; 72 | font-size: 14px; 73 | } 74 | 75 | #about-content { 76 | background-color: #ffd; 77 | border: 1px solid #fc0; 78 | margin-left: -11px; 79 | } 80 | #about-content table { 81 | margin-top: 10px; 82 | margin-bottom: 10px; 83 | font-size: 11px; 84 | border-collapse: collapse; 85 | } 86 | #about-content td { 87 | padding: 10px; 88 | padding-top: 3px; 89 | padding-bottom: 3px; 90 | } 91 | #about-content td.name {color: #555} 92 | #about-content td.value {color: #000} 93 | 94 | #about-content.failure { 95 | background-color: #fcc; 96 | border: 1px solid #f00; 97 | } 98 | #about-content.failure p { 99 | margin: 0; 100 | padding: 10px; 101 | } 102 | 103 | #getting-started { 104 | border-top: 1px solid #ccc; 105 | margin-top: 25px; 106 | padding-top: 15px; 107 | } 108 | #getting-started h1 { 109 | margin: 0; 110 | font-size: 20px; 111 | } 112 | #getting-started h2 { 113 | margin: 0; 114 | font-size: 14px; 115 | font-weight: normal; 116 | color: #333; 117 | margin-bottom: 25px; 118 | } 119 | #getting-started ol { 120 | margin-left: 0; 121 | padding-left: 0; 122 | } 123 | #getting-started li { 124 | font-size: 18px; 125 | color: #888; 126 | margin-bottom: 25px; 127 | } 128 | #getting-started li h2 { 129 | margin: 0; 130 | font-weight: normal; 131 | font-size: 18px; 132 | color: #333; 133 | } 134 | #getting-started li p { 135 | color: #555; 136 | font-size: 13px; 137 | } 138 | 139 | #search { 140 | margin: 0; 141 | padding-top: 10px; 142 | padding-bottom: 10px; 143 | font-size: 11px; 144 | } 145 | #search input { 146 | font-size: 11px; 147 | margin: 2px; 148 | } 149 | #search-text {width: 170px} 150 | 151 | #sidebar ul { 152 | margin-left: 0; 153 | padding-left: 0; 154 | } 155 | #sidebar ul h3 { 156 | margin-top: 25px; 157 | font-size: 16px; 158 | padding-bottom: 10px; 159 | border-bottom: 1px solid #ccc; 160 | } 161 | #sidebar li { 162 | list-style-type: none; 163 | } 164 | #sidebar ul.links li { 165 | margin-bottom: 5px; 166 | } 167 | 168 | h1, h2, h3, h4, h5 { 169 | font-family: sans-serif; 170 | margin: 1.2em 0 0.6em 0; 171 | } 172 | 173 | p { 174 | line-height: 1.5em; 175 | margin: 1.6em 0; 176 | } 177 | 178 | code, tt { 179 | font-family: 'Andale Mono', Monaco, 'Liberation Mono', 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', monospace; 180 | } 181 | 182 | #footer { 183 | clear: both; 184 | padding-top: 2em; 185 | text-align: center; 186 | padding-right: 160px; 187 | font-family: sans-serif; 188 | font-size: 10px; 189 | } 190 | -------------------------------------------------------------------------------- /public/datetimepicker-master/.gitignore: -------------------------------------------------------------------------------- 1 | index.php -------------------------------------------------------------------------------- /public/datetimepicker-master/MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 http://xdsoft.net 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /public/datetimepicker-master/README.md: -------------------------------------------------------------------------------- 1 | datetimepicker 2 | ============== 3 | [Documentation][doc] 4 | 5 | 6 | jQuery Plugin Date and Time Picker 7 | 8 | DateTimePicker 9 | 10 | ![ScreenShot](https://raw2.github.com/xdan/datetimepicker/master/screen/1.png) 11 | 12 | DatePicker 13 | 14 | ![ScreenShot](https://raw2.github.com/xdan/datetimepicker/master/screen/2.png) 15 | 16 | TimePicker 17 | 18 | ![ScreenShot](https://raw2.github.com/xdan/datetimepicker/master/screen/3.png) 19 | 20 | [doc]: http://xdsoft.net/jqplugins/datetimepicker/ 21 | -------------------------------------------------------------------------------- /public/datetimepicker-master/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"datetimepicker", 3 | "version":"2.3.4", 4 | "main": [ 5 | "jquery.datetimepicker.js", 6 | "jquery.datetimepicker.css" 7 | ], 8 | "ignore": [ 9 | "**/screen", 10 | "**/datetimepicker.jquery.json", 11 | "**/*.png", 12 | "**/*.txt", 13 | "**/*.md", 14 | "**/*.html", 15 | "**/*.tpl" 16 | ], 17 | "keywords": [ 18 | "calendar", 19 | "date", 20 | "time", 21 | "form", 22 | "datetime", 23 | "datepicker", 24 | "timepicker", 25 | "datetimepicker", 26 | "validation", 27 | "ui", 28 | "scroller", 29 | "picker", 30 | "i18n", 31 | "input", 32 | "jquery", 33 | "touch" 34 | ], 35 | "dependencies": { 36 | "jquery": ">= 1.7.2" 37 | }, 38 | "authors": [ 39 | { 40 | "name": "Chupurnov Valeriy", 41 | "email": "chupurnov@gmail.com", 42 | "homepage": "http://xdsoft.net/contacts.html" 43 | } 44 | ], 45 | "homepage":"http://xdsoft.net/jqplugins/datetimepicker/", 46 | "repository": { 47 | "type": "git", "url": "git://github.com:xdan/datetimepicker.git" 48 | } 49 | } -------------------------------------------------------------------------------- /public/datetimepicker-master/datetimepicker.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "datetimepicker", 3 | "version": "2.3.4", 4 | "title": "jQuery Date and Time picker", 5 | "description": "jQuery plugin for date, time, or datetime manipulation in form", 6 | "keywords": [ 7 | "calendar", 8 | "date", 9 | "time", 10 | "form", 11 | "datetime", 12 | "datepicker", 13 | "timepicker", 14 | "datetimepicker", 15 | "validation", 16 | "ui", 17 | "scroller", 18 | "picker", 19 | "i18n", 20 | "input", 21 | "jquery", 22 | "touch" 23 | ], 24 | "author": { 25 | "name": "Chupurnov Valeriy", 26 | "email": "chupurnov@gmail.com", 27 | "url": "http://xdsoft.net/contacts.html" 28 | }, 29 | "maintainers": [{ 30 | "name": "Chupurnov Valeriy", 31 | "email": "chupurnov@gmail.com", 32 | "url": "http://xdsoft.net" 33 | }], 34 | "licenses": [ 35 | { 36 | "type": "MIT", 37 | "url": "https://github.com/xdan/datetimepicker/blob/master/MIT-LICENSE.txt" 38 | } 39 | ], 40 | "bugs": "https://github.com/xdan/datetimepicker/issues", 41 | "homepage": "http://xdsoft.net/jqplugins/datetimepicker/", 42 | "docs": "http://xdsoft.net/jqplugins/datetimepicker/", 43 | "download": "https://github.com/xdan/datetimepicker/archive/master.zip", 44 | "dependencies": { 45 | "jquery": ">=1.7" 46 | } 47 | } -------------------------------------------------------------------------------- /public/datetimepicker-master/screen/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/datetimepicker-master/screen/1.png -------------------------------------------------------------------------------- /public/datetimepicker-master/screen/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/datetimepicker-master/screen/2.png -------------------------------------------------------------------------------- /public/datetimepicker-master/screen/3.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/datetimepicker-master/screen/3.1.png -------------------------------------------------------------------------------- /public/datetimepicker-master/screen/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/datetimepicker-master/screen/3.png -------------------------------------------------------------------------------- /public/dispatch.cgi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use Dancer ':syntax'; 3 | use FindBin '$RealBin'; 4 | use Plack::Runner; 5 | 6 | # For some reason Apache SetEnv directives dont propagate 7 | # correctly to the dispatchers, so forcing PSGI and env here 8 | # is safer. 9 | set apphandler => 'PSGI'; 10 | set environment => 'production'; 11 | 12 | my $psgi = path($RealBin, '..', 'bin', 'app.pl'); 13 | die "Unable to read startup script: $psgi" unless -r $psgi; 14 | 15 | Plack::Runner->run($psgi); 16 | -------------------------------------------------------------------------------- /public/dispatch.fcgi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use Dancer ':syntax'; 3 | use FindBin '$RealBin'; 4 | use Plack::Handler::FCGI; 5 | 6 | # For some reason Apache SetEnv directives dont propagate 7 | # correctly to the dispatchers, so forcing PSGI and env here 8 | # is safer. 9 | set apphandler => 'PSGI'; 10 | set environment => 'production'; 11 | 12 | my $psgi = path($RealBin, '..', 'bin', 'app.pl'); 13 | my $app = do($psgi); 14 | die "Unable to read startup script: $@" if $@; 15 | my $server = Plack::Handler::FCGI->new(nproc => 5, detach => 1); 16 | 17 | $server->run($app); 18 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/favicon.ico -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/font-awesome-4.0.3/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/font-awesome-4.0.3/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/font-awesome-4.0.3/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/font-awesome-4.0.3/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .@{fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font-family: FontAwesome; 7 | font-style: normal; 8 | font-weight: normal; 9 | line-height: 1; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "spinning"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: -@fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon-rotate(@degrees, @rotation) { 5 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation); 6 | -webkit-transform: rotate(@degrees); 7 | -moz-transform: rotate(@degrees); 8 | -ms-transform: rotate(@degrees); 9 | -o-transform: rotate(@degrees); 10 | transform: rotate(@degrees); 11 | } 12 | 13 | .fa-icon-flip(@horiz, @vert, @rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1); 15 | -webkit-transform: scale(@horiz, @vert); 16 | -moz-transform: scale(@horiz, @vert); 17 | -ms-transform: scale(@horiz, @vert); 18 | -o-transform: scale(@horiz, @vert); 19 | transform: scale(@horiz, @vert); 20 | } 21 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); 7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), 8 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), 9 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), 10 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); 11 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/less/spinning.less: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: spin 2s infinite linear; 6 | -moz-animation: spin 2s infinite linear; 7 | -o-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | } 10 | 11 | @-moz-keyframes spin { 12 | 0% { -moz-transform: rotate(0deg); } 13 | 100% { -moz-transform: rotate(359deg); } 14 | } 15 | @-webkit-keyframes spin { 16 | 0% { -webkit-transform: rotate(0deg); } 17 | 100% { -webkit-transform: rotate(359deg); } 18 | } 19 | @-o-keyframes spin { 20 | 0% { -o-transform: rotate(0deg); } 21 | 100% { -o-transform: rotate(359deg); } 22 | } 23 | @-ms-keyframes spin { 24 | 0% { -ms-transform: rotate(0deg); } 25 | 100% { -ms-transform: rotate(359deg); } 26 | } 27 | @keyframes spin { 28 | 0% { transform: rotate(0deg); } 29 | 100% { transform: rotate(359deg); } 30 | } 31 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font-family: FontAwesome; 7 | font-style: normal; 8 | font-weight: normal; 9 | line-height: 1; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon-rotate($degrees, $rotation) { 5 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation); 6 | -webkit-transform: rotate($degrees); 7 | -moz-transform: rotate($degrees); 8 | -ms-transform: rotate($degrees); 9 | -o-transform: rotate($degrees); 10 | transform: rotate($degrees); 11 | } 12 | 13 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation); 15 | -webkit-transform: scale($horiz, $vert); 16 | -moz-transform: scale($horiz, $vert); 17 | -ms-transform: scale($horiz, $vert); 18 | -o-transform: scale($horiz, $vert); 19 | transform: scale($horiz, $vert); 20 | } 21 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 9 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 10 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 11 | //src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/scss/_spinning.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: spin 2s infinite linear; 6 | -moz-animation: spin 2s infinite linear; 7 | -o-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | } 10 | 11 | @-moz-keyframes spin { 12 | 0% { -moz-transform: rotate(0deg); } 13 | 100% { -moz-transform: rotate(359deg); } 14 | } 15 | @-webkit-keyframes spin { 16 | 0% { -webkit-transform: rotate(0deg); } 17 | 100% { -webkit-transform: rotate(359deg); } 18 | } 19 | @-o-keyframes spin { 20 | 0% { -o-transform: rotate(0deg); } 21 | 100% { -o-transform: rotate(359deg); } 22 | } 23 | @-ms-keyframes spin { 24 | 0% { -ms-transform: rotate(0deg); } 25 | 100% { -ms-transform: rotate(359deg); } 26 | } 27 | @keyframes spin { 28 | 0% { transform: rotate(0deg); } 29 | 100% { transform: rotate(359deg); } 30 | } 31 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /public/font-awesome-4.0.3/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "spinning"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /public/images/gradient.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/images/gradient.jpg -------------------------------------------------------------------------------- /public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/images/logo.png -------------------------------------------------------------------------------- /public/images/logo_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/images/logo_medium.png -------------------------------------------------------------------------------- /public/images/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/images/logo_small.png -------------------------------------------------------------------------------- /public/images/logo_xsmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/images/logo_xsmall.png -------------------------------------------------------------------------------- /public/images/perldancer-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/images/perldancer-bg.jpg -------------------------------------------------------------------------------- /public/images/perldancer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/images/perldancer.jpg -------------------------------------------------------------------------------- /public/images/track.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/images/track.gif -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | 4 | node_modules/* 5 | custom/* 6 | 7 | docs/index.md 8 | -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2014 Nick Downie 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/README.md: -------------------------------------------------------------------------------- 1 | # Chart.js 2 | 3 | *Simple HTML5 Charts using the canvas element* [chartjs.org](http://www.chartjs.org) 4 | 5 | ## Documentation 6 | 7 | You can find documentation at [chartjs.org/docs](http://www.chartjs.org/docs). The markdown files that build the site are available under `/docs`. Please note - in some of the json examples of configuration you might notice some liquid tags - this is just for the generating the site html, please disregard. 8 | 9 | ## License 10 | 11 | Chart.js is available under the [MIT license](http://opensource.org/licenses/MIT). 12 | 13 | ## Bugs & issues 14 | 15 | When reporting bugs or issues, if you could include a link to a simple [jsbin](http://jsbin.com) or similar demonstrating the issue, that'd be really helpful. 16 | 17 | 18 | ## Contributing 19 | New contributions to the library are welcome, just a couple of guidelines: 20 | 21 | - Tabs for indentation, not spaces please. 22 | - Please ensure you're changing the individual files in `/src`, not the concatenated output in the `Chart.js` file in the root of the repo. 23 | - Please check that your code will pass `jshint` code standards, `gulp jshint` will run this for you. 24 | - Please keep pull requests concise, and document new functionality in the relevant `.md` file. 25 | - Consider whether your changes are useful for all users, or if creating a Chart.js extension would be more appropriate. 26 | - Please avoid committing in the build Chart.js & Chart.min.js file, as it causes conflicts when merging. 27 | -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Chart.js", 3 | "version": "1.0.1-beta.4", 4 | "description": "Simple HTML5 Charts using the canvas element", 5 | "homepage": "https://github.com/nnnick/Chart.js", 6 | "author": "nnnick", 7 | "main": [ 8 | "Chart.min.js" 9 | ], 10 | "dependencies": {} 11 | } -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/docs/02-Bar-Chart.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Bar Chart 3 | anchor: bar-chart 4 | --- 5 | 6 | ### Introduction 7 | A bar chart is a way of showing data as bars. 8 | 9 | It is sometimes used to show trend data, and the comparison of multiple data sets side by side. 10 | 11 |
12 | 13 |
14 | 15 | ### Example usage 16 | ```javascript 17 | var myBarChart = new Chart(ctx).Bar(data, options); 18 | ``` 19 | 20 | ### Data structure 21 | 22 | ```javascript 23 | var data = { 24 | labels: ["January", "February", "March", "April", "May", "June", "July"], 25 | datasets: [ 26 | { 27 | label: "My First dataset", 28 | fillColor: "rgba(220,220,220,0.5)", 29 | strokeColor: "rgba(220,220,220,0.8)", 30 | highlightFill: "rgba(220,220,220,0.75)", 31 | highlightStroke: "rgba(220,220,220,1)", 32 | data: [65, 59, 80, 81, 56, 55, 40] 33 | }, 34 | { 35 | label: "My Second dataset", 36 | fillColor: "rgba(151,187,205,0.5)", 37 | strokeColor: "rgba(151,187,205,0.8)", 38 | highlightFill: "rgba(151,187,205,0.75)", 39 | highlightStroke: "rgba(151,187,205,1)", 40 | data: [28, 48, 40, 19, 86, 27, 90] 41 | } 42 | ] 43 | }; 44 | ``` 45 | The bar chart has the a very similar data structure to the line chart, and has an array of datasets, each with colours and an array of data. Again, colours are in CSS format. 46 | We have an array of labels too for display. In the example, we are showing the same data as the previous line chart example. 47 | 48 | The label key on each dataset is optional, and can be used when generating a scale for the chart. 49 | 50 | ### Chart Options 51 | 52 | These are the customisation options specific to Bar charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart. 53 | 54 | ```javascript 55 | { 56 | //Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value 57 | scaleBeginAtZero : true, 58 | 59 | //Boolean - Whether grid lines are shown across the chart 60 | scaleShowGridLines : true, 61 | 62 | //String - Colour of the grid lines 63 | scaleGridLineColor : "rgba(0,0,0,.05)", 64 | 65 | //Number - Width of the grid lines 66 | scaleGridLineWidth : 1, 67 | 68 | //Boolean - If there is a stroke on each bar 69 | barShowStroke : true, 70 | 71 | //Number - Pixel width of the bar stroke 72 | barStrokeWidth : 2, 73 | 74 | //Number - Spacing between each of the X value sets 75 | barValueSpacing : 5, 76 | 77 | //Number - Spacing between data sets within X values 78 | barDatasetSpacing : 1, 79 | {% raw %} 80 | //String - A legend template 81 | legendTemplate : "
    -legend\"><% for (var i=0; i
  • \"><%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>
" 82 | {% endraw %} 83 | } 84 | ``` 85 | 86 | You can override these for your `Chart` instance by passing a second argument into the `Bar` method as an object with the keys you want to override. 87 | 88 | For example, we could have a bar chart without a stroke on each bar by doing the following: 89 | 90 | ```javascript 91 | new Chart(ctx).Bar(data, { 92 | barShowStroke: false 93 | }); 94 | // This will create a chart with all of the default options, merged from the global config, 95 | // and the Bar chart defaults but this particular instance will have `barShowStroke` set to false. 96 | ``` 97 | 98 | We can also change these defaults values for each Bar type that is created, this object is available at `Chart.defaults.Bar`. 99 | 100 | ### Prototype methods 101 | 102 | #### .getBarsAtEvent( event ) 103 | 104 | Calling `getBarsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the bar elements that are at that the same position of that event. 105 | 106 | ```javascript 107 | canvas.onclick = function(evt){ 108 | var activeBars = myBarChart.getBarsAtEvent(evt); 109 | // => activeBars is an array of bars on the canvas that are at the same position as the click event. 110 | }; 111 | ``` 112 | 113 | This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application. 114 | 115 | #### .update( ) 116 | 117 | Calling `update()` on your Chart instance will re-render the chart with any updated values, allowing you to edit the value of multiple existing points, then render those in one animated render loop. 118 | 119 | ```javascript 120 | myBarChart.datasets[0].bars[2].value = 50; 121 | // Would update the first dataset's value of 'March' to be 50 122 | myBarChart.update(); 123 | // Calling update now animates the position of March from 90 to 50. 124 | ``` 125 | 126 | #### .addData( valuesArray, label ) 127 | 128 | Calling `addData(valuesArray, label)` on your Chart instance passing an array of values for each dataset, along with a label for those bars. 129 | 130 | ```javascript 131 | // The values array passed into addData should be one for each dataset in the chart 132 | myBarChart.addData([40, 60], "August"); 133 | // The new data will now animate at the end of the chart. 134 | ``` 135 | 136 | #### .removeData( ) 137 | 138 | Calling `removeData()` on your Chart instance will remove the first value for all datasets on the chart. 139 | 140 | ```javascript 141 | myBarChart.removeData(); 142 | // The chart will now animate and remove the first bar 143 | ``` -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/docs/07-Notes.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Notes 3 | anchor: notes 4 | --- 5 | 6 | ### Browser support 7 | Browser support for the canvas element is available in all modern & major mobile browsers (caniuse.com/canvas). 8 | 9 | For IE8 & below, I would recommend using the polyfill ExplorerCanvas - available at https://code.google.com/p/explorercanvas/. It falls back to Internet explorer's format VML when canvas support is not available. Example use: 10 | 11 | ```html 12 | 13 | 16 | 17 | ``` 18 | 19 | Usually I would recommend feature detection to choose whether or not to load a polyfill, rather than IE conditional comments, however in this case, VML is a Microsoft proprietary format, so it will only work in IE. 20 | 21 | Some important points to note in my experience using ExplorerCanvas as a fallback. 22 | 23 | - Initialise charts on load rather than DOMContentReady when using the library, as sometimes a race condition will occur, and it will result in an error when trying to get the 2d context of a canvas. 24 | - New VML DOM elements are being created for each animation frame and there is no hardware acceleration. As a result animation is usually slow and jerky, with flashing text. It is a good idea to dynamically turn off animation based on canvas support. I recommend using the excellent Modernizr to do this. 25 | - When declaring fonts, the library explorercanvas requires the font name to be in single quotes inside the string. For example, instead of your scaleFontFamily property being simply "Arial", explorercanvas support, use "'Arial'" instead. Chart.js does this for default values. 26 | 27 | ### Bugs & issues 28 | 29 | Please report these on the GitHub page - at github.com/nnnick/Chart.js. If you could include a link to a simple jsbin or similar to demonstrate the issue, that'd be really helpful. 30 | 31 | 32 | ### Contributing 33 | New contributions to the library are welcome, just a couple of guidelines: 34 | 35 | - Tabs for indentation, not spaces please. 36 | - Please ensure you're changing the individual files in `/src`, not the concatenated output in the `Chart.js` file in the root of the repo. 37 | - Please check that your code will pass `jshint` code standards, `gulp jshint` will run this for you. 38 | - Please keep pull requests concise, and document new functionality in the relevant `.md` file. 39 | - Consider whether your changes are useful for all users, or if creating a Chart.js extension would be more appropriate. 40 | 41 | ### License 42 | Chart.js is open source and available under the MIT license. -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | concat = require('gulp-concat'), 3 | uglify = require('gulp-uglify'), 4 | util = require('gulp-util'), 5 | jshint = require('gulp-jshint'), 6 | size = require('gulp-size'), 7 | connect = require('gulp-connect'), 8 | replace = require('gulp-replace'), 9 | inquirer = require('inquirer'), 10 | semver = require('semver'), 11 | exec = require('child_process').exec, 12 | fs = require('fs'), 13 | package = require('./package.json'), 14 | bower = require('./bower.json'); 15 | 16 | var srcDir = './src/'; 17 | /* 18 | * Usage : gulp build --types=Bar,Line,Doughnut 19 | * Output: - A built Chart.js file with Core and types Bar, Line and Doughnut concatenated together 20 | * - A minified version of this code, in Chart.min.js 21 | */ 22 | 23 | gulp.task('build', function(){ 24 | 25 | // Default to all of the chart types, with Chart.Core first 26 | var srcFiles = [FileName('Core')], 27 | isCustom = !!(util.env.types), 28 | outputDir = (isCustom) ? 'custom' : '.'; 29 | if (isCustom){ 30 | util.env.types.split(',').forEach(function(type){ return srcFiles.push(FileName(type))}); 31 | } 32 | else{ 33 | // Seems gulp-concat remove duplicates - nice! 34 | // So we can use this to sort out dependency order - aka include Core first! 35 | srcFiles.push(srcDir+'*'); 36 | } 37 | 38 | return gulp.src(srcFiles) 39 | .pipe(concat('Chart.js')) 40 | .pipe(replace('{{ version }}', package.version)) 41 | .pipe(gulp.dest(outputDir)) 42 | .pipe(uglify({preserveComments:'some'})) 43 | .pipe(concat('Chart.min.js')) 44 | .pipe(gulp.dest(outputDir)); 45 | 46 | function FileName(moduleName){ 47 | return srcDir+'Chart.'+moduleName+'.js'; 48 | }; 49 | }); 50 | 51 | /* 52 | * Usage : gulp bump 53 | * Prompts: Version increment to bump 54 | * Output: - New version number written into package.json & bower.json 55 | */ 56 | 57 | gulp.task('bump', function(complete){ 58 | util.log('Current version:', util.colors.cyan(package.version)); 59 | var choices = ['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'].map(function(versionType){ 60 | return versionType + ' (v' + semver.inc(package.version, versionType) + ')'; 61 | }); 62 | inquirer.prompt({ 63 | type: 'list', 64 | name: 'version', 65 | message: 'What version update would you like?', 66 | choices: choices 67 | }, function(res){ 68 | var increment = res.version.split(' ')[0], 69 | newVersion = semver.inc(package.version, increment); 70 | 71 | // Set the new versions into the bower/package object 72 | package.version = newVersion; 73 | bower.version = newVersion; 74 | 75 | // Write these to their own files, then build the output 76 | fs.writeFileSync('package.json', JSON.stringify(package, null, 2)); 77 | fs.writeFileSync('bower.json', JSON.stringify(bower, null, 2)); 78 | 79 | complete(); 80 | }); 81 | }); 82 | 83 | gulp.task('release', ['build'], function(){ 84 | exec('git tag -a v' + package.version); 85 | }); 86 | 87 | gulp.task('jshint', function(){ 88 | return gulp.src(srcDir + '*.js') 89 | .pipe(jshint()) 90 | .pipe(jshint.reporter('default')); 91 | }); 92 | 93 | gulp.task('library-size', function(){ 94 | return gulp.src('Chart.min.js') 95 | .pipe(size({ 96 | gzip: true 97 | })); 98 | }); 99 | 100 | gulp.task('module-sizes', function(){ 101 | return gulp.src(srcDir + '*.js') 102 | .pipe(uglify({preserveComments:'some'})) 103 | .pipe(size({ 104 | showFiles: true, 105 | gzip: true 106 | })) 107 | }); 108 | 109 | gulp.task('watch', function(){ 110 | gulp.watch('./src/*', ['build']); 111 | }); 112 | 113 | gulp.task('test', ['jshint']); 114 | 115 | gulp.task('size', ['library-size', 'module-sizes']); 116 | 117 | gulp.task('default', ['build', 'watch']); 118 | 119 | gulp.task('server', function(){ 120 | connect.server({ 121 | port: 8000, 122 | }); 123 | }); 124 | 125 | // Convenience task for opening the project straight from the command line 126 | gulp.task('_open', function(){ 127 | exec('open http://localhost:8000'); 128 | exec('subl .'); 129 | }); 130 | 131 | gulp.task('dev', ['server', 'default']); 132 | -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chart.js", 3 | "homepage": "http://www.chartjs.org", 4 | "description": "Simple HTML5 charts using the canvas element.", 5 | "version": "1.0.1-beta.4", 6 | "main": "Chart.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/nnnick/Chart.js.git" 10 | }, 11 | "dependences": {}, 12 | "devDependencies": { 13 | "gulp": "3.5.x", 14 | "gulp-concat": "~2.1.x", 15 | "gulp-connect": "~2.0.5", 16 | "gulp-jshint": "~1.5.1", 17 | "gulp-replace": "^0.4.0", 18 | "gulp-size": "~0.4.0", 19 | "gulp-uglify": "~0.2.x", 20 | "gulp-util": "~2.2.x", 21 | "inquirer": "^0.5.1", 22 | "semver": "^3.0.1" 23 | } 24 | } -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/samples/bar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Bar Chart 5 | 6 | 7 | 8 |
9 | 10 |
11 | 12 | 13 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/samples/doughnut.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Doughnut Chart 5 | 6 | 15 | 16 | 17 |
18 | 19 |
20 | 21 | 22 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/samples/line.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Line Chart 5 | 6 | 7 | 8 |
9 |
10 | 11 |
12 |
13 | 14 | 15 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/samples/pie.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pie Chart 5 | 6 | 7 | 8 |
9 | 10 |
11 | 12 | 13 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/samples/polar-area.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Polar Area Chart 5 | 6 | 7 | 8 |
9 | 10 |
11 | 12 | 13 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /public/javascripts/Chart.js-master/samples/radar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Radar Chart 5 | 6 | 7 | 11 | 12 | 13 |
14 | 15 |
16 | 17 | 18 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/jquery.tinymce.min.js: -------------------------------------------------------------------------------- 1 | !function(e){function t(){function t(e){"remove"===e&&this.each(function(e,t){var n=r(t);n&&n.remove()}),this.find("span.mceEditor,div.mceEditor").each(function(e,t){var n=tinymce.get(t.id.replace(/_parent$/,""));n&&n.remove()})}function i(e){var n,i=this;if(null!=e)t.call(i),i.each(function(t,n){var i;(i=tinymce.get(n.id))&&i.setContent(e)});else if(i.length>0&&(n=tinymce.get(i[0].id)))return n.getContent()}function r(e){var t=null;return e&&e.id&&a.tinymce&&(t=tinymce.get(e.id)),t}function c(e){return!!(e&&e.length&&a.tinymce&&e.is(":tinymce"))}var o={};e.each(["text","html","val"],function(t,a){var u=o[a]=e.fn[a],s="text"===a;e.fn[a]=function(t){var a=this;if(!c(a))return u.apply(a,arguments);if(t!==n)return i.call(a.filter(":tinymce"),t),u.apply(a.not(":tinymce"),arguments),a;var o="",l=arguments;return(s?a:a.eq(0)).each(function(t,n){var i=r(n);o+=i?s?i.getContent().replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g,""):i.getContent({save:!0}):u.apply(e(n),l)}),o}}),e.each(["append","prepend"],function(t,i){var a=o[i]=e.fn[i],u="prepend"===i;e.fn[i]=function(e){var t=this;return c(t)?e!==n?(t.filter(":tinymce").each(function(t,n){var i=r(n);i&&i.setContent(u?e+i.getContent():i.getContent()+e)}),a.apply(t.not(":tinymce"),arguments),t):void 0:a.apply(t,arguments)}}),e.each(["remove","replaceWith","replaceAll","empty"],function(n,i){var r=o[i]=e.fn[i];e.fn[i]=function(){return t.call(this,i),r.apply(this,arguments)}}),o.attr=e.fn.attr,e.fn.attr=function(t,a){var u=this,s=arguments;if(!t||"value"!==t||!c(u))return a!==n?o.attr.apply(u,s):o.attr.apply(u,s);if(a!==n)return i.call(u.filter(":tinymce"),a),o.attr.apply(u.not(":tinymce"),s),u;var l=u[0],m=r(l);return m?m.getContent({save:!0}):o.attr.apply(e(l),s)}}var n,i,r=[],a=window;e.fn.tinymce=function(n){function c(){var i=[],r=0;l||(t(),l=!0),m.each(function(e,t){var a,c=t.id,o=n.oninit;c||(t.id=c=tinymce.DOM.uniqueId()),tinymce.get(c)||(a=new tinymce.Editor(c,n,tinymce.EditorManager),i.push(a),a.on("init",function(){var e,t=o;m.css("visibility",""),o&&++r==i.length&&("string"==typeof t&&(e=-1===t.indexOf(".")?null:tinymce.resolve(t.replace(/\.\w+$/,"")),t=tinymce.resolve(t)),t.apply(e||tinymce,i))}))}),e.each(i,function(e,t){t.render()})}var o,u,s,l,m=this,p="";if(!m.length)return m;if(!n)return window.tinymce?tinymce.get(m[0].id):null;if(m.css("visibility","hidden"),a.tinymce||i||!(o=n.script_url))1===i?r.push(c):c();else{i=1,u=o.substring(0,o.lastIndexOf("/")),-1!=o.indexOf(".min")&&(p=".min"),a.tinymce=a.tinyMCEPreInit||{base:u,suffix:p},-1!=o.indexOf("gzip")&&(s=n.language||"en",o=o+(/\?/.test(o)?"&":"?")+"js=true&core=true&suffix="+escape(p)+"&themes="+escape(n.theme||"modern")+"&plugins="+escape(n.plugins||"")+"&languages="+(s||""),a.tinyMCE_GZ||(a.tinyMCE_GZ={start:function(){function t(e){tinymce.ScriptLoader.markDone(tinymce.baseURI.toAbsolute(e))}t("langs/"+s+".js"),t("themes/"+n.theme+"/theme"+p+".js"),t("themes/"+n.theme+"/langs/"+s+".js"),e.each(n.plugins.split(","),function(e,n){n&&(t("plugins/"+n+"/plugin"+p+".js"),t("plugins/"+n+"/langs/"+s+".js"))})},end:function(){}}));var f=document.createElement("script");f.type="text/javascript",f.onload=f.onreadystatechange=function(t){t=t||window.event,2===i||"load"!=t.type&&!/complete|loaded/.test(f.readyState)||(tinymce.dom.Event.domLoaded=1,i=2,n.script_loaded&&n.script_loaded(),c(),e.each(r,function(e,t){t()}))},f.src=o,document.body.appendChild(f)}return m},e.extend(e.expr[":"],{tinymce:function(e){return!!(e.id&&"tinymce"in window&&tinymce.get(e.id))}})}(jQuery); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/langs/readme.md: -------------------------------------------------------------------------------- 1 | This is where language files should be placed. 2 | 3 | Please DO NOT translate these directly use this service: https://www.transifex.com/projects/p/tinymce/ 4 | -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/advlist/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("advlist",function(t){function e(t,e){var n=[];return tinymce.each(e.split(/[ ,]/),function(t){n.push({text:t.replace(/\-/g," ").replace(/\b\w/g,function(t){return t.toUpperCase()}),data:"default"==t?"":t})}),n}function n(e,n){var o,l=t.dom,a=t.selection;o=l.getParent(a.getNode(),"ol,ul"),o&&o.nodeName==e&&n!==!1||t.execCommand("UL"==e?"InsertUnorderedList":"InsertOrderedList"),n=n===!1?i[e]:n,i[e]=n,o=l.getParent(a.getNode(),"ol,ul"),o&&n&&(l.setStyle(o,"listStyleType",n),o.removeAttribute("data-mce-style")),t.focus()}function o(e){var n=t.dom.getStyle(t.dom.getParent(t.selection.getNode(),"ol,ul"),"listStyleType")||"";e.control.items().each(function(t){t.active(t.settings.data===n)})}var l,a,i={};l=e("OL",t.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman")),a=e("UL",t.getParam("advlist_bullet_styles","default,circle,disc,square")),t.addButton("numlist",{type:"splitbutton",tooltip:"Numbered list",menu:l,onshow:o,onselect:function(t){n("OL",t.control.settings.data)},onclick:function(){n("OL",!1)}}),t.addButton("bullist",{type:"splitbutton",tooltip:"Bullet list",menu:a,onshow:o,onselect:function(t){n("UL",t.control.settings.data)},onclick:function(){n("UL",!1)}})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/anchor/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("anchor",function(n){function e(){var e=n.selection.getNode(),t="";"A"==e.tagName&&(t=e.name||e.id||""),n.windowManager.open({title:"Anchor",body:{type:"textbox",name:"name",size:40,label:"Name",value:t},onsubmit:function(e){n.execCommand("mceInsertContent",!1,n.dom.createHTML("a",{id:e.data.name}))}})}n.addButton("anchor",{icon:"anchor",tooltip:"Anchor",onclick:e,stateSelector:"a:not([href])"}),n.addMenuItem("anchor",{icon:"anchor",text:"Anchor",context:"insert",onclick:e})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/autolink/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("autolink",function(n){function t(n){o(n,-1,"(",!0)}function e(n){o(n,0,"",!0)}function i(n){o(n,-1,"",!1)}function o(n,t,e){function i(n,t){if(0>t&&(t=0),3==n.nodeType){var e=n.data.length;t>e&&(t=e)}return t}function o(n,t){f.setStart(n,i(n,t))}function r(n,t){f.setEnd(n,i(n,t))}var f,d,a,s,c,l,u,g,h,C;if(f=n.selection.getRng(!0).cloneRange(),f.startOffset<5){if(g=f.endContainer.previousSibling,!g){if(!f.endContainer.firstChild||!f.endContainer.firstChild.nextSibling)return;g=f.endContainer.firstChild.nextSibling}if(h=g.length,o(g,h),r(g,h),f.endOffset<5)return;d=f.endOffset,s=g}else{if(s=f.endContainer,3!=s.nodeType&&s.firstChild){for(;3!=s.nodeType&&s.firstChild;)s=s.firstChild;3==s.nodeType&&(o(s,0),r(s,s.nodeValue.length))}d=1==f.endOffset?2:f.endOffset-1-t}a=d;do o(s,d>=2?d-2:0),r(s,d>=1?d-1:0),d-=1,C=f.toString();while(" "!=C&&""!==C&&160!=C.charCodeAt(0)&&d-2>=0&&C!=e);f.toString()==e||160==f.toString().charCodeAt(0)?(o(s,d),r(s,a),d+=1):0===f.startOffset?(o(s,0),r(s,a)):(o(s,d),r(s,a)),l=f.toString(),"."==l.charAt(l.length-1)&&r(s,a-1),l=f.toString(),u=l.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i),u&&("www."==u[1]?u[1]="http://www.":/@$/.test(u[1])&&!/^mailto:/.test(u[1])&&(u[1]="mailto:"+u[1]),c=n.selection.getBookmark(),n.selection.setRng(f),n.execCommand("createlink",!1,u[1]+u[2]),n.selection.moveToBookmark(c),n.nodeChanged())}var r;return n.on("keydown",function(t){return 13==t.keyCode?i(n):void 0}),tinymce.Env.ie?void n.on("focus",function(){if(!r){r=!0;try{n.execCommand("AutoUrlDetect",!1,!0)}catch(t){}}}):(n.on("keypress",function(e){return 41==e.keyCode?t(n):void 0}),void n.on("keyup",function(t){return 32==t.keyCode?e(n):void 0}))}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/autoresize/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("autoresize",function(e){function t(){return e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen()}function i(o){var r,s,g,m,l,d,u,h,f,c,_,p,y=tinymce.DOM;if(s=e.getDoc()){if(g=s.body,m=s.documentElement,l=n.autoresize_min_height,!g||o&&"setcontent"===o.type&&o.initial||t())return void(g&&m&&(g.style.overflowY="auto",m.style.overflowY="auto"));u=e.dom.getStyle(g,"margin-top",!0),h=e.dom.getStyle(g,"margin-bottom",!0),f=e.dom.getStyle(g,"padding-top",!0),c=e.dom.getStyle(g,"padding-bottom",!0),_=e.dom.getStyle(g,"border-top-width",!0),p=e.dom.getStyle(g,"border-bottom-width",!0),d=g.offsetHeight+parseInt(u,10)+parseInt(h,10)+parseInt(f,10)+parseInt(c,10)+parseInt(_,10)+parseInt(p,10),(isNaN(d)||0>=d)&&(d=tinymce.Env.ie?g.scrollHeight:tinymce.Env.webkit&&0===g.clientHeight?0:g.offsetHeight),d>n.autoresize_min_height&&(l=d),n.autoresize_max_height&&d>n.autoresize_max_height?(l=n.autoresize_max_height,g.style.overflowY="auto",m.style.overflowY="auto"):(g.style.overflowY="hidden",m.style.overflowY="hidden",g.scrollTop=0),l!==a&&(r=l-a,y.setStyle(e.iframeElement,"height",l+"px"),a=l,tinymce.isWebKit&&0>r&&i(o))}}function o(e,t,n){setTimeout(function(){i({}),e--?o(e,t,n):n&&n()},t)}var n=e.settings,a=0;e.settings.inline||(n.autoresize_min_height=parseInt(e.getParam("autoresize_min_height",e.getElement().offsetHeight),10),n.autoresize_max_height=parseInt(e.getParam("autoresize_max_height",0),10),e.on("init",function(){var t=e.getParam("autoresize_overflow_padding",1);e.dom.setStyles(e.getBody(),{paddingBottom:e.getParam("autoresize_bottom_margin",50),paddingLeft:t,paddingRight:t})}),e.on("nodechange setcontent keyup FullscreenStateChanged",i),e.getParam("autoresize_on_init",!0)&&e.on("init",function(){o(20,100,function(){o(5,1e3)})}),e.addCommand("mceAutoResize",i))}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/autosave/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce._beforeUnloadHandler=function(){var e;return tinymce.each(tinymce.editors,function(t){t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&t.getParam("autosave_ask_before_unload",!0)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))}),e},tinymce.PluginManager.add("autosave",function(e){function t(e,t){var n={s:1e3,m:6e4};return e=/^(\d+)([ms]?)$/.exec(""+(e||t)),(e[2]?n[e[2]]:1)*parseInt(e,10)}function n(){var e=parseInt(v.getItem(c+"time"),10)||0;return(new Date).getTime()-e>m.autosave_retention?(a(!1),!1):!0}function a(t){v.removeItem(c+"draft"),v.removeItem(c+"time"),t!==!1&&e.fire("RemoveDraft")}function r(){!f()&&e.isDirty()&&(v.setItem(c+"draft",e.getContent({format:"raw",no_events:!0})),v.setItem(c+"time",(new Date).getTime()),e.fire("StoreDraft"))}function o(){n()&&(e.setContent(v.getItem(c+"draft"),{format:"raw"}),e.fire("RestoreDraft"))}function i(){d||(setInterval(function(){e.removed||r()},m.autosave_interval),d=!0)}function s(){var t=this;t.disabled(!n()),e.on("StoreDraft RestoreDraft RemoveDraft",function(){t.disabled(!n())}),i()}function u(){e.undoManager.beforeChange(),o(),a(),e.undoManager.add()}function f(t){var n=e.settings.forced_root_block;return t=tinymce.trim("undefined"==typeof t?e.getBody().innerHTML:t),""===t||new RegExp("^<"+n+"[^>]*>(( | |[ ]|]*>)+?|)|
$","i").test(t)}var c,d,m=e.settings,v=tinymce.util.LocalStorage;c=m.autosave_prefix||"tinymce-autosave-{path}{query}-{id}-",c=c.replace(/\{path\}/g,document.location.pathname),c=c.replace(/\{query\}/g,document.location.search),c=c.replace(/\{id\}/g,e.id),m.autosave_interval=t(m.autosave_interval,"30s"),m.autosave_retention=t(m.autosave_retention,"20m"),e.addButton("restoredraft",{title:"Restore last draft",onclick:u,onPostRender:s}),e.addMenuItem("restoredraft",{text:"Restore last draft",onclick:u,onPostRender:s,context:"file"}),e.settings.autosave_restore_when_empty!==!1&&(e.on("init",function(){n()&&f()&&o()}),e.on("saveContent",function(){a()})),window.onbeforeunload=tinymce._beforeUnloadHandler,this.hasDraft=n,this.storeDraft=r,this.restoreDraft=o,this.removeDraft=a,this.isEmpty=f}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/bbcode/plugin.min.js: -------------------------------------------------------------------------------- 1 | !function(){tinymce.create("tinymce.plugins.BBCodePlugin",{init:function(o){var e=this,t=o.getParam("bbcode_dialect","punbb").toLowerCase();o.on("beforeSetContent",function(o){o.content=e["_"+t+"_bbcode2html"](o.content)}),o.on("postProcess",function(o){o.set&&(o.content=e["_"+t+"_bbcode2html"](o.content)),o.get&&(o.content=e["_"+t+"_html2bbcode"](o.content))})},getInfo:function(){return{longname:"BBCode Plugin",author:"Moxiecode Systems AB",authorurl:"http://www.tinymce.com",infourl:"http://www.tinymce.com/wiki.php/Plugin:bbcode"}},_punbb_html2bbcode:function(o){function e(e,t){o=o.replace(e,t)}return o=tinymce.trim(o),e(/(.*?)<\/a>/gi,"[url=$1]$2[/url]"),e(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),e(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),e(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),e(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),e(/(.*?)<\/span>/gi,"[color=$1]$2[/color]"),e(/(.*?)<\/font>/gi,"[color=$1]$2[/color]"),e(/(.*?)<\/span>/gi,"[size=$1]$2[/size]"),e(/(.*?)<\/font>/gi,"$1"),e(//gi,"[img]$1[/img]"),e(/(.*?)<\/span>/gi,"[code]$1[/code]"),e(/(.*?)<\/span>/gi,"[quote]$1[/quote]"),e(/(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"),e(/(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"),e(/(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"),e(/(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"),e(/(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"),e(/(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"),e(/<\/(strong|b)>/gi,"[/b]"),e(/<(strong|b)>/gi,"[b]"),e(/<\/(em|i)>/gi,"[/i]"),e(/<(em|i)>/gi,"[i]"),e(/<\/u>/gi,"[/u]"),e(/(.*?)<\/span>/gi,"[u]$1[/u]"),e(//gi,"[u]"),e(/]*>/gi,"[quote]"),e(/<\/blockquote>/gi,"[/quote]"),e(/
/gi,"\n"),e(//gi,"\n"),e(/
/gi,"\n"),e(/

/gi,""),e(/<\/p>/gi,"\n"),e(/ |\u00a0/gi," "),e(/"/gi,'"'),e(/</gi,"<"),e(/>/gi,">"),e(/&/gi,"&"),o},_punbb_bbcode2html:function(o){function e(e,t){o=o.replace(e,t)}return o=tinymce.trim(o),e(/\n/gi,"
"),e(/\[b\]/gi,""),e(/\[\/b\]/gi,""),e(/\[i\]/gi,""),e(/\[\/i\]/gi,""),e(/\[u\]/gi,""),e(/\[\/u\]/gi,""),e(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'$2'),e(/\[url\](.*?)\[\/url\]/gi,'$1'),e(/\[img\](.*?)\[\/img\]/gi,''),e(/\[color=(.*?)\](.*?)\[\/color\]/gi,'$2'),e(/\[code\](.*?)\[\/code\]/gi,'$1 '),e(/\[quote.*?\](.*?)\[\/quote\]/gi,'$1 '),o}}),tinymce.PluginManager.add("bbcode",tinymce.plugins.BBCodePlugin)}(); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/code/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("code",function(e){function o(){var o=e.windowManager.open({title:"Source code",body:{type:"textbox",name:"code",multiline:!0,minWidth:e.getParam("code_dialog_width",600),minHeight:e.getParam("code_dialog_height",Math.min(tinymce.DOM.getViewPort().h-200,500)),spellcheck:!1,style:"direction: ltr; text-align: left"},onSubmit:function(o){e.focus(),e.undoManager.transact(function(){e.setContent(o.data.code)}),e.selection.setCursorLocation(),e.nodeChanged()}});o.find("#code").value(e.getContent({source_view:!0}))}e.addCommand("mceCodeEditor",o),e.addButton("code",{icon:"code",tooltip:"Source code",onclick:o}),e.addMenuItem("code",{icon:"code",text:"Source code",context:"tools",onclick:o})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/colorpicker/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("colorpicker",function(e){function n(n,a){function i(e){var n=new tinymce.util.Color(e),a=n.toRgb();l.fromJSON({r:a.r,g:a.g,b:a.b,hex:n.toHex().substr(1)}),t(n.toHex())}function t(e){l.find("#preview")[0].getEl().style.background=e}var l=e.windowManager.open({title:"Color",items:{type:"container",layout:"flex",direction:"row",align:"stretch",padding:5,spacing:10,items:[{type:"colorpicker",value:a,onchange:function(){var e=this.rgb();l&&(l.find("#r").value(e.r),l.find("#g").value(e.g),l.find("#b").value(e.b),l.find("#hex").value(this.value().substr(1)),t(this.value()))}},{type:"form",padding:0,labelGap:5,defaults:{type:"textbox",size:7,value:"0",flex:1,spellcheck:!1,onchange:function(){var e,n,a=l.find("colorpicker")[0];return e=this.name(),n=this.value(),"hex"==e?(n="#"+n,i(n),void a.value(n)):(n={r:l.find("#r").value(),g:l.find("#g").value(),b:l.find("#b").value()},a.value(n),void i(n))}},items:[{name:"r",label:"R",autofocus:1},{name:"g",label:"G"},{name:"b",label:"B"},{name:"hex",label:"#",value:"000000"},{name:"preview",type:"container",border:1}]}]},onSubmit:function(){n("#"+this.toJSON().hex)}});i(a)}e.settings.color_picker_callback||(e.settings.color_picker_callback=n)}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/contextmenu/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("contextmenu",function(e){var t,n=e.settings.contextmenu_never_use_native;e.on("contextmenu",function(o){var i,c=e.getDoc();if(!o.ctrlKey||n){if(o.preventDefault(),tinymce.Env.mac&&tinymce.Env.webkit&&2==o.button&&c.caretRangeFromPoint&&e.selection.setRng(c.caretRangeFromPoint(o.x,o.y)),i=e.settings.contextmenu||"link image inserttable | cell row column deletetable",t)t.show();else{var a=[];tinymce.each(i.split(/[ ,]/),function(t){var n=e.menuItems[t];"|"==t&&(n={text:t}),n&&(n.shortcut="",a.push(n))});for(var r=0;r'}),t+=""}),t+=""}var i=[["cool","cry","embarassed","foot-in-mouth"],["frown","innocent","kiss","laughing"],["money-mouth","sealed","smile","surprised"],["tongue-out","undecided","wink","yell"]];t.addButton("emoticons",{type:"panelbutton",panel:{role:"application",autohide:!0,html:a,onclick:function(e){var a=t.dom.getParent(e.target,"a");a&&(t.insertContent(''+a.getAttribute('),this.hide())}},tooltip:"Emoticons"})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/example/dialog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Custom dialog

5 | Input some text: 6 | 7 | 8 | -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/example/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("example",function(t,e){t.addButton("example",{text:"My button",icon:!1,onclick:function(){t.windowManager.open({title:"Example plugin",body:[{type:"textbox",name:"title",label:"Title"}],onsubmit:function(e){t.insertContent("Title: "+e.data.title)}})}}),t.addMenuItem("example",{text:"Example plugin",context:"tools",onclick:function(){t.windowManager.open({title:"TinyMCE site",url:e+"/dialog.html",width:600,height:400,buttons:[{text:"Insert",onclick:function(){var e=t.windowManager.getWindows()[0];t.insertContent(e.getContentWindow().document.getElementById("content").value),e.close()}},{text:"Close",onclick:"close"}]})}})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/example_dependency/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("example_dependency",function(){},["example"]); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/fullscreen/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("fullscreen",function(e){function t(){var e,t,n=window,i=document,l=i.body;return l.offsetWidth&&(e=l.offsetWidth,t=l.offsetHeight),n.innerWidth&&n.innerHeight&&(e=n.innerWidth,t=n.innerHeight),{w:e,h:t}}function n(){function n(){d.setStyle(a,"height",t().h-(h.clientHeight-a.clientHeight))}var u,h,a,f,m=document.body,g=document.documentElement;s=!s,h=e.getContainer(),u=h.style,a=e.getContentAreaContainer().firstChild,f=a.style,s?(i=f.width,l=f.height,f.width=f.height="100%",c=u.width,o=u.height,u.width=u.height="",d.addClass(m,"mce-fullscreen"),d.addClass(g,"mce-fullscreen"),d.addClass(h,"mce-fullscreen"),d.bind(window,"resize",n),n(),r=n):(f.width=i,f.height=l,c&&(u.width=c),o&&(u.height=o),d.removeClass(m,"mce-fullscreen"),d.removeClass(g,"mce-fullscreen"),d.removeClass(h,"mce-fullscreen"),d.unbind(window,"resize",r)),e.fire("FullscreenStateChanged",{state:s})}var i,l,r,c,o,s=!1,d=tinymce.DOM;return e.settings.inline?void 0:(e.on("init",function(){e.addShortcut("Ctrl+Alt+F","",n)}),e.on("remove",function(){r&&d.unbind(window,"resize",r)}),e.addCommand("mceFullScreen",n),e.addMenuItem("fullscreen",{text:"Fullscreen",shortcut:"Ctrl+Alt+F",selectable:!0,onClick:n,onPostRender:function(){var t=this;e.on("FullscreenStateChanged",function(e){t.active(e.state)})},context:"view"}),e.addButton("fullscreen",{tooltip:"Fullscreen",shortcut:"Ctrl+Alt+F",onClick:n,onPostRender:function(){var t=this;e.on("FullscreenStateChanged",function(e){t.active(e.state)})}}),{isFullscreen:function(){return s}})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/hr/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("hr",function(n){n.addCommand("InsertHorizontalRule",function(){n.execCommand("mceInsertContent",!1,"
")}),n.addButton("hr",{icon:"hr",tooltip:"Horizontal line",cmd:"InsertHorizontalRule"}),n.addMenuItem("hr",{icon:"hr",text:"Horizontal line",cmd:"InsertHorizontalRule",context:"insert"})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/image/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("image",function(e){function t(e,t){function i(e,i){n.parentNode&&n.parentNode.removeChild(n),t({width:e,height:i})}var n=document.createElement("img");n.onload=function(){i(n.clientWidth,n.clientHeight)},n.onerror=function(){i()};var a=n.style;a.visibility="hidden",a.position="fixed",a.bottom=a.left=0,a.width=a.height="auto",document.body.appendChild(n),n.src=e}function i(e,t,i){function n(e,i){return i=i||[],tinymce.each(e,function(e){var a={text:e.text||e.title};e.menu?a.menu=n(e.menu):(a.value=e.value,t(a)),i.push(a)}),i}return n(e,i||[])}function n(t){return function(){var i=e.settings.image_list;"string"==typeof i?tinymce.util.XHR.send({url:i,success:function(e){t(tinymce.util.JSON.parse(e))}}):"function"==typeof i?i(t):t(i)}}function a(n){function a(){var e,t,i,n;e=c.find("#width")[0],t=c.find("#height")[0],e&&t&&(i=e.value(),n=t.value(),c.find("#constrain")[0].checked()&&d&&u&&i&&n&&(d!=i?(n=Math.round(i/d*n),t.value(n)):(i=Math.round(n/u*i),e.value(i))),d=i,u=n)}function l(){function t(t){function i(){t.onload=t.onerror=null,e.selection&&(e.selection.select(t),e.nodeChanged())}t.onload=function(){m.width||m.height||!y||p.setAttribs(t,{width:t.clientWidth,height:t.clientHeight}),i()},t.onerror=i}s(),a(),m=tinymce.extend(m,c.toJSON()),m.alt||(m.alt=""),""===m.width&&(m.width=null),""===m.height&&(m.height=null),m.style||(m.style=null),m={src:m.src,alt:m.alt,width:m.width,height:m.height,style:m.style,"class":m["class"]},e.undoManager.transact(function(){return m.src?(f?p.setAttribs(f,m):(m.id="__mcenew",e.focus(),e.selection.setContent(p.createHTML("img",m)),f=p.get("__mcenew"),p.setAttrib(f,"id",null)),void t(f)):void(f&&(p.remove(f),e.focus(),e.nodeChanged()))})}function o(e){return e&&(e=e.replace(/px$/,"")),e}function r(i){var n=i.meta||{};g&&g.value(e.convertURL(this.value(),"src")),tinymce.each(n,function(e,t){c.find("#"+t).value(e)}),n.width||n.height||t(this.value(),function(e){e.width&&e.height&&y&&(d=e.width,u=e.height,c.find("#width").value(d),c.find("#height").value(u))})}function s(){function t(e){return e.length>0&&/^[0-9]+$/.test(e)&&(e+="px"),e}if(e.settings.image_advtab){var i=c.toJSON(),n=p.parseStyle(i.style);delete n.margin,n["margin-top"]=n["margin-bottom"]=t(i.vspace),n["margin-left"]=n["margin-right"]=t(i.hspace),n["border-width"]=t(i.border),c.find("#style").value(p.serializeStyle(p.parseStyle(p.serializeStyle(n))))}}var c,d,u,g,h,m={},p=e.dom,f=e.selection.getNode(),y=e.settings.image_dimensions!==!1;d=p.getAttrib(f,"width"),u=p.getAttrib(f,"height"),"IMG"!=f.nodeName||f.getAttribute("data-mce-object")||f.getAttribute("data-mce-placeholder")?f=null:m={src:p.getAttrib(f,"src"),alt:p.getAttrib(f,"alt"),"class":p.getAttrib(f,"class"),width:d,height:u},n&&(g={type:"listbox",label:"Image list",values:i(n,function(t){t.value=e.convertURL(t.value||t.url,"src")},[{text:"None",value:""}]),value:m.src&&e.convertURL(m.src,"src"),onselect:function(e){var t=c.find("#alt");(!t.value()||e.lastControl&&t.value()==e.lastControl.text())&&t.value(e.control.text()),c.find("#src").value(e.control.value()).fire("change")},onPostRender:function(){g=this}}),e.settings.image_class_list&&(h={name:"class",type:"listbox",label:"Class",values:i(e.settings.image_class_list,function(t){t.value&&(t.textStyle=function(){return e.formatter.getCssText({inline:"img",classes:[t.value]})})})});var b=[{name:"src",type:"filepicker",filetype:"image",label:"Source",autofocus:!0,onchange:r},g];e.settings.image_description!==!1&&b.push({name:"alt",type:"textbox",label:"Image description"}),y&&b.push({type:"container",label:"Dimensions",layout:"flex",direction:"row",align:"center",spacing:5,items:[{name:"width",type:"textbox",maxLength:5,size:3,onchange:a,ariaLabel:"Width"},{type:"label",text:"x"},{name:"height",type:"textbox",maxLength:5,size:3,onchange:a,ariaLabel:"Height"},{name:"constrain",type:"checkbox",checked:!0,text:"Constrain proportions"}]}),b.push(h),e.settings.image_advtab?(f&&(m.hspace=o(f.style.marginLeft||f.style.marginRight),m.vspace=o(f.style.marginTop||f.style.marginBottom),m.border=o(f.style.borderWidth),m.style=e.dom.serializeStyle(e.dom.parseStyle(e.dom.getAttrib(f,"style")))),c=e.windowManager.open({title:"Insert/edit image",data:m,bodyType:"tabpanel",body:[{title:"General",type:"form",items:b},{title:"Advanced",type:"form",pack:"start",items:[{label:"Style",name:"style",type:"textbox"},{type:"form",layout:"grid",packV:"start",columns:2,padding:0,alignH:["left","right"],defaults:{type:"textbox",maxWidth:50,onchange:s},items:[{label:"Vertical space",name:"vspace"},{label:"Horizontal space",name:"hspace"},{label:"Border",name:"border"}]}]}],onSubmit:l})):c=e.windowManager.open({title:"Insert/edit image",data:m,body:b,onSubmit:l})}e.addButton("image",{icon:"image",tooltip:"Insert/edit image",onclick:n(a),stateSelector:"img:not([data-mce-object],[data-mce-placeholder])"}),e.addMenuItem("image",{icon:"image",text:"Insert image",onclick:n(a),context:"insert",prependToContext:!0}),e.addCommand("mceImage",n(a))}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/importcss/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("importcss",function(t){function e(t){return"string"==typeof t?function(e){return-1!==e.indexOf(t)}:t instanceof RegExp?function(e){return t.test(e)}:t}function n(e,n){function i(t,e){var c,o=t.href;if(o&&n(o,e)){s(t.imports,function(t){i(t,!0)});try{c=t.cssRules||t.rules}catch(a){}s(c,function(t){t.styleSheet?i(t.styleSheet,!0):t.selectorText&&s(t.selectorText.split(","),function(t){r.push(tinymce.trim(t))})})}}var r=[],c={};s(t.contentCSS,function(t){c[t]=!0}),n||(n=function(t,e){return e||c[t]});try{s(e.styleSheets,function(t){i(t)})}catch(o){}return r}function i(e){var n,i=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(e);if(i){var r=i[1],s=i[2].substr(1).split(".").join(" "),c=tinymce.makeMap("a,img");return i[1]?(n={title:e},t.schema.getTextBlockElements()[r]?n.block=r:t.schema.getBlockElements()[r]||c[r.toLowerCase()]?n.selector=r:n.inline=r):i[2]&&(n={inline:"span",title:e.substr(1),classes:s}),t.settings.importcss_merge_classes!==!1?n.classes=s:n.attributes={"class":s},n}}var r=this,s=tinymce.each;t.on("renderFormatsMenu",function(c){var o=t.settings,a={},l=o.importcss_selector_converter||i,f=e(o.importcss_selector_filter),m=c.control;t.settings.importcss_append||m.items().remove();var u=[];tinymce.each(o.importcss_groups,function(t){t=tinymce.extend({},t),t.filter=e(t.filter),u.push(t)}),s(n(c.doc||t.getDoc(),e(o.importcss_file_filter)),function(e){if(-1===e.indexOf(".mce-")&&!a[e]&&(!f||f(e))){var n,i=l.call(r,e);if(i){var s=i.name||tinymce.DOM.uniqueId();if(u)for(var c=0;c'+n+"";var i=e.dom.getParent(e.selection.getStart(),"time");if(i)return void e.dom.setOuterHTML(i,n)}e.insertContent(n)}var n,r,i="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),d="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),c="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),m="January February March April May June July August September October November December".split(" "),u=[];e.addCommand("mceInsertDate",function(){a(e.getParam("insertdatetime_dateformat",e.translate("%Y-%m-%d")))}),e.addCommand("mceInsertTime",function(){a(e.getParam("insertdatetime_timeformat",e.translate("%H:%M:%S")))}),e.addButton("insertdatetime",{type:"splitbutton",title:"Insert date/time",onclick:function(){a(n||r)},menu:u}),tinymce.each(e.settings.insertdatetime_formats||["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"],function(e){r||(r=e),u.push({text:t(e),onclick:function(){n=e,a(e)}})}),e.addMenuItem("insertdatetime",{icon:"date",text:"Insert date/time",menu:u,context:"insert"})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/layer/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("layer",function(e){function t(e){do if(e.className&&-1!=e.className.indexOf("mceItemLayer"))return e;while(e=e.parentNode)}function o(t){var o=e.dom;tinymce.each(o.select("div,p",t),function(e){/^(absolute|relative|fixed)$/i.test(e.style.position)&&(e.hasVisual?o.addClass(e,"mceItemVisualAid"):o.removeClass(e,"mceItemVisualAid"),o.addClass(e,"mceItemLayer"))})}function d(o){var d,n,a=[],i=t(e.selection.getNode()),s=-1,l=-1;for(n=[],tinymce.walk(e.getBody(),function(e){1==e.nodeType&&/^(absolute|relative|static)$/i.test(e.style.position)&&n.push(e)},"childNodes"),d=0;ds&&n[d]==i&&(s=d);if(0>o){for(d=0;d-1?(n[s].style.zIndex=a[l],n[l].style.zIndex=a[s]):a[s]>0&&(n[s].style.zIndex=a[s]-1)}else{for(d=0;da[s]){l=d;break}l>-1?(n[s].style.zIndex=a[l],n[l].style.zIndex=a[s]):n[s].style.zIndex=a[s]+1}e.execCommand("mceRepaint")}function n(){var t=e.dom,o=t.getPos(t.getParent(e.selection.getNode(),"*")),d=e.getBody();e.dom.add(d,"div",{style:{position:"absolute",left:o.x,top:o.y>20?o.y:20,width:100,height:100},"class":"mceItemVisualAid mceItemLayer"},e.selection.getContent()||e.getLang("layer.content")),tinymce.Env.ie&&t.setHTML(d,d.innerHTML)}function a(){var o=t(e.selection.getNode());o||(o=e.dom.getParent(e.selection.getNode(),"DIV,P,IMG")),o&&("absolute"==o.style.position.toLowerCase()?(e.dom.setStyles(o,{position:"",left:"",top:"",width:"",height:""}),e.dom.removeClass(o,"mceItemVisualAid"),e.dom.removeClass(o,"mceItemLayer")):(o.style.left||(o.style.left="20px"),o.style.top||(o.style.top="20px"),o.style.width||(o.style.width=o.width?o.width+"px":"100px"),o.style.height||(o.style.height=o.height?o.height+"px":"100px"),o.style.position="absolute",e.dom.setAttrib(o,"data-mce-style",""),e.addVisual(e.getBody())),e.execCommand("mceRepaint"),e.nodeChanged())}e.addCommand("mceInsertLayer",n),e.addCommand("mceMoveForward",function(){d(1)}),e.addCommand("mceMoveBackward",function(){d(-1)}),e.addCommand("mceMakeAbsolute",function(){a()}),e.addButton("moveforward",{title:"layer.forward_desc",cmd:"mceMoveForward"}),e.addButton("movebackward",{title:"layer.backward_desc",cmd:"mceMoveBackward"}),e.addButton("absolute",{title:"layer.absolute_desc",cmd:"mceMakeAbsolute"}),e.addButton("insertlayer",{title:"layer.insertlayer_desc",cmd:"mceInsertLayer"}),e.on("init",function(){tinymce.Env.ie&&e.getDoc().execCommand("2D-Position",!1,!0)}),e.on("mouseup",function(o){var d=t(o.target);d&&e.dom.setAttrib(d,"data-mce-style","")}),e.on("mousedown",function(o){var d,n=o.target,a=e.getDoc();tinymce.Env.gecko&&(t(n)?"on"!==a.designMode&&(a.designMode="on",n=a.body,d=n.parentNode,d.removeChild(n),d.appendChild(n)):"on"==a.designMode&&(a.designMode="off"))}),e.on("NodeChange",o)}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/legacyoutput/plugin.min.js: -------------------------------------------------------------------------------- 1 | !function(e){e.on("AddEditor",function(e){e.editor.settings.inline_styles=!1}),e.PluginManager.add("legacyoutput",function(t,n,i){t.on("init",function(){var n="p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",i=e.explode(t.settings.font_size_style_values),a=t.schema;t.formatter.register({alignleft:{selector:n,attributes:{align:"left"}},aligncenter:{selector:n,attributes:{align:"center"}},alignright:{selector:n,attributes:{align:"right"}},alignjustify:{selector:n,attributes:{align:"justify"}},bold:[{inline:"b",remove:"all"},{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}}],italic:[{inline:"i",remove:"all"},{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}}],underline:[{inline:"u",remove:"all"},{inline:"span",styles:{textDecoration:"underline"},exact:!0}],strikethrough:[{inline:"strike",remove:"all"},{inline:"span",styles:{textDecoration:"line-through"},exact:!0}],fontname:{inline:"font",attributes:{face:"%value"}},fontsize:{inline:"font",attributes:{size:function(t){return e.inArray(i,t.value)+1}}},forecolor:{inline:"font",attributes:{color:"%value"}},hilitecolor:{inline:"font",styles:{backgroundColor:"%value"}}}),e.each("b,i,u,strike".split(","),function(e){a.addValidElements(e+"[*]")}),a.getElementRule("font")||a.addValidElements("font[face|size|color|style]"),e.each(n.split(","),function(e){var t=a.getElementRule(e);t&&(t.attributes.align||(t.attributes.align={},t.attributesOrder.push("align")))})}),t.addButton("fontsizeselect",function(){var e=[],n="8pt=1 10pt=2 12pt=3 14pt=4 18pt=5 24pt=6 36pt=7",i=t.settings.fontsize_formats||n;return t.$.each(i.split(" "),function(t,n){var i=n,a=n,o=n.split("=");o.length>1&&(i=o[0],a=o[1]),e.push({text:i,value:a})}),{type:"listbox",text:"Font Sizes",tooltip:"Font Sizes",values:e,fixedWidth:!0,onPostRender:function(){var e=this;t.on("NodeChange",function(){var n;n=t.dom.getParent(t.selection.getNode(),"font"),e.value(n?n.size:"")})},onclick:function(e){e.control.settings.value&&t.execCommand("FontSize",!1,e.control.settings.value)}}}),t.addButton("fontselect",function(){function e(e){e=e.replace(/;$/,"").split(";");for(var t=e.length;t--;)e[t]=e[t].split("=");return e}var n="Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",a=[],o=e(t.settings.font_formats||n);return i.each(o,function(e,t){a.push({text:{raw:t[0]},value:t[1],textStyle:-1==t[1].indexOf("dings")?"font-family:"+t[1]:""})}),{type:"listbox",text:"Font Family",tooltip:"Font Family",values:a,fixedWidth:!0,onPostRender:function(){var e=this;t.on("NodeChange",function(){var n;n=t.dom.getParent(t.selection.getNode(),"font"),e.value(n?n.face:"")})},onselect:function(e){e.control.settings.value&&t.execCommand("FontName",!1,e.control.settings.value)}}})})}(tinymce); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/link/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("link",function(t){function e(e){return function(){var n=t.settings.link_list;"string"==typeof n?tinymce.util.XHR.send({url:n,success:function(t){e(tinymce.util.JSON.parse(t))}}):"function"==typeof n?n(e):e(n)}}function n(t,e,n){function i(t,n){return n=n||[],tinymce.each(t,function(t){var l={text:t.text||t.title};t.menu?l.menu=i(t.menu):(l.value=t.value,e&&e(l)),n.push(l)}),n}return i(t,n||[])}function i(e){function i(t){var e=f.find("#text");(!e.value()||t.lastControl&&e.value()==t.lastControl.text())&&e.value(t.control.text()),f.find("#href").value(t.control.value())}function l(e){var n=[];return tinymce.each(t.dom.select("a:not([href])"),function(t){var i=t.name||t.id;i&&n.push({text:i,value:"#"+i,selected:-1!=e.indexOf("#"+i)})}),n.length?(n.unshift({text:"None",value:""}),{name:"anchor",type:"listbox",label:"Anchors",values:n,onselect:i}):void 0}function a(){!c&&0===y.text.length&&d&&this.parent().parent().find("#text")[0].value(this.value())}function o(e){var n=e.meta||{};x&&x.value(t.convertURL(this.value(),"href")),tinymce.each(e.meta,function(t,e){f.find("#"+e).value(t)}),n.text||a.call(this)}function r(t){var e=b.getContent();if(/]+>[^<]+<\/a>$/.test(e)||-1==e.indexOf("href=")))return!1;if(t){var n,i=t.childNodes;if(0===i.length)return!1;for(n=i.length-1;n>=0;n--)if(3!=i[n].nodeType)return!1}return!0}var s,u,c,f,d,g,x,v,h,m,p,k,y={},b=t.selection,_=t.dom;s=b.getNode(),u=_.getParent(s,"a[href]"),d=r(),y.text=c=u?u.innerText||u.textContent:b.getContent({format:"text"}),y.href=u?_.getAttrib(u,"href"):"",(k=_.getAttrib(u,"target"))?y.target=k:t.settings.default_link_target&&(y.target=t.settings.default_link_target),(k=_.getAttrib(u,"rel"))&&(y.rel=k),(k=_.getAttrib(u,"class"))&&(y["class"]=k),(k=_.getAttrib(u,"title"))&&(y.title=k),d&&(g={name:"text",type:"textbox",size:40,label:"Text to display",onchange:function(){y.text=this.value()}}),e&&(x={type:"listbox",label:"Link list",values:n(e,function(e){e.value=t.convertURL(e.value||e.url,"href")},[{text:"None",value:""}]),onselect:i,value:t.convertURL(y.href,"href"),onPostRender:function(){x=this}}),t.settings.target_list!==!1&&(t.settings.target_list||(t.settings.target_list=[{text:"None",value:""},{text:"New window",value:"_blank"}]),h={name:"target",type:"listbox",label:"Target",values:n(t.settings.target_list)}),t.settings.rel_list&&(v={name:"rel",type:"listbox",label:"Rel",values:n(t.settings.rel_list)}),t.settings.link_class_list&&(m={name:"class",type:"listbox",label:"Class",values:n(t.settings.link_class_list,function(e){e.value&&(e.textStyle=function(){return t.formatter.getCssText({inline:"a",classes:[e.value]})})})}),t.settings.link_title!==!1&&(p={name:"title",type:"textbox",label:"Title",value:y.title}),f=t.windowManager.open({title:"Insert link",data:y,body:[{name:"href",type:"filepicker",filetype:"file",size:40,autofocus:!0,label:"Url",onchange:o,onkeyup:a},g,p,l(y.href),x,v,h,m],onSubmit:function(e){function n(e,n){var i=t.selection.getRng();window.setTimeout(function(){t.windowManager.confirm(e,function(e){t.selection.setRng(i),n(e)})},0)}function i(){var e={href:l,target:y.target?y.target:null,rel:y.rel?y.rel:null,"class":y["class"]?y["class"]:null,title:y.title?y.title:null};u?(t.focus(),d&&y.text!=c&&("innerText"in u?u.innerText=y.text:u.textContent=y.text),_.setAttribs(u,e),b.select(u),t.undoManager.add()):d?t.insertContent(_.createHTML("a",e,_.encode(y.text))):t.execCommand("mceInsertLink",!1,e)}var l;return y=tinymce.extend(y,e.data),(l=y.href)?l.indexOf("@")>0&&-1==l.indexOf("//")&&-1==l.indexOf("mailto:")?void n("The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",function(t){t&&(l="mailto:"+l),i()}):/^\s*www\./i.test(l)?void n("The URL you entered seems to be an external link. Do you want to add the required http:// prefix?",function(t){t&&(l="http://"+l),i()}):void i():void t.execCommand("unlink")}})}t.addButton("link",{icon:"link",tooltip:"Insert/edit link",shortcut:"Ctrl+K",onclick:e(i),stateSelector:"a[href]"}),t.addButton("unlink",{icon:"unlink",tooltip:"Remove link",cmd:"unlink",stateSelector:"a[href]"}),t.addShortcut("Ctrl+K","",e(i)),t.addCommand("mceLink",e(i)),this.showDialog=i,t.addMenuItem("link",{icon:"link",text:"Insert link",shortcut:"Ctrl+K",onclick:e(i),stateSelector:"a[href]",context:"insert",prependToContext:!0})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/media/moxieplayer.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/tinymce/js/tinymce/plugins/media/moxieplayer.swf -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/nonbreaking/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("nonbreaking",function(n){var e=n.getParam("nonbreaking_force_tab");if(n.addCommand("mceNonBreaking",function(){n.insertContent(n.plugins.visualchars&&n.plugins.visualchars.state?' ':" "),n.dom.setAttrib(n.dom.select("span.mce-nbsp"),"data-mce-bogus","1")}),n.addButton("nonbreaking",{title:"Nonbreaking space",cmd:"mceNonBreaking"}),n.addMenuItem("nonbreaking",{text:"Nonbreaking space",cmd:"mceNonBreaking",context:"insert"}),e){var a=+e>1?+e:3;n.on("keydown",function(e){if(9==e.keyCode){if(e.shiftKey)return;e.preventDefault();for(var t=0;a>t;t++)n.execCommand("mceNonBreaking")}})}}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/noneditable/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("noneditable",function(e){function t(e){var t;if(1===e.nodeType){if(t=e.getAttribute(u),t&&"inherit"!==t)return t;if(t=e.contentEditable,"inherit"!==t)return t}return null}function n(e){for(var n;e;){if(n=t(e))return"false"===n?e:null;e=e.parentNode}}function r(){function r(e){for(;e;){if(e.id===g)return e;e=e.parentNode}}function a(e){var t;if(e)for(t=new f(e,e),e=t.current();e;e=t.next())if(3===e.nodeType)return e}function i(n,r){var a,i;return"false"===t(n)&&u.isBlock(n)?void s.select(n):(i=u.createRng(),"true"===t(n)&&(n.firstChild||n.appendChild(e.getDoc().createTextNode(" ")),n=n.firstChild,r=!0),a=u.create("span",{id:g,"data-mce-bogus":!0},m),r?n.parentNode.insertBefore(a,n):u.insertAfter(a,n),i.setStart(a.firstChild,1),i.collapse(!0),s.setRng(i),a)}function o(e){var t,n,i,o;if(e)t=s.getRng(!0),t.setStartBefore(e),t.setEndBefore(e),n=a(e),n&&n.nodeValue.charAt(0)==m&&(n=n.deleteData(0,1)),u.remove(e,!0),s.setRng(t);else for(i=r(s.getStart());(e=u.get(g))&&e!==o;)i!==e&&(n=a(e),n&&n.nodeValue.charAt(0)==m&&(n=n.deleteData(0,1)),u.remove(e,!0)),o=e}function l(){function e(e,n){var r,a,i,o,l;if(r=d.startContainer,a=d.startOffset,3==r.nodeType){if(l=r.nodeValue.length,a>0&&l>a||(n?a==l:0===a))return}else{if(!(a0?a-1:a;r=r.childNodes[u],r.hasChildNodes()&&(r=r.firstChild)}for(i=new f(r,e);o=i[n?"prev":"next"]();){if(3===o.nodeType&&o.nodeValue.length>0)return;if("true"===t(o))return o}return e}var r,a,l,d,u;o(),l=s.isCollapsed(),r=n(s.getStart()),a=n(s.getEnd()),(r||a)&&(d=s.getRng(!0),l?(r=r||a,(u=e(r,!0))?i(u,!0):(u=e(r,!1))?i(u,!1):s.select(r)):(d=s.getRng(!0),r&&d.setStartBefore(r),a&&d.setEndAfter(a),s.setRng(d)))}function d(a){function i(e,t){for(;e=e[t?"previousSibling":"nextSibling"];)if(3!==e.nodeType||e.nodeValue.length>0)return e}function d(e,t){s.select(e),s.collapse(t)}function g(a){function i(e){for(var t=d;t;){if(t===e)return;t=t.parentNode}u.remove(e),l()}function o(){var r,o,l=e.schema.getNonEmptyElements();for(o=new tinymce.dom.TreeWalker(d,e.getBody());(r=a?o.prev():o.next())&&!l[r.nodeName.toLowerCase()]&&!(3===r.nodeType&&tinymce.trim(r.nodeValue).length>0);)if("false"===t(r))return i(r),!0;return n(r)?!0:!1}var f,d,c,g;if(s.isCollapsed()){if(f=s.getRng(!0),d=f.startContainer,c=f.startOffset,d=r(d)||d,g=n(d))return i(g),!1;if(3==d.nodeType&&(a?c>0:ch||h>124)&&h!=c.DELETE&&h!=c.BACKSPACE){if((tinymce.isMac?a.metaKey:a.ctrlKey)&&(67==h||88==h||86==h))return;if(a.preventDefault(),h==c.LEFT||h==c.RIGHT){var y=h==c.LEFT;if(e.dom.isBlock(m)){var T=y?m.previousSibling:m.nextSibling,C=new f(T,T),b=y?C.prev():C.next();d(b,!y)}else d(m,y)}}else if(h==c.LEFT||h==c.RIGHT||h==c.BACKSPACE||h==c.DELETE){if(p=r(v)){if(h==c.LEFT||h==c.BACKSPACE)if(m=i(p,!0),m&&"false"===t(m)){if(a.preventDefault(),h!=c.LEFT)return void u.remove(m);d(m,!0)}else o(p);if(h==c.RIGHT||h==c.DELETE)if(m=i(p),m&&"false"===t(m)){if(a.preventDefault(),h!=c.RIGHT)return void u.remove(m);d(m,!1)}else o(p)}if((h==c.BACKSPACE||h==c.DELETE)&&!g(h==c.BACKSPACE))return a.preventDefault(),!1}}var u=e.dom,s=e.selection,g="mce_noneditablecaret",m="";e.on("mousedown",function(n){var r=e.selection.getNode();"false"===t(r)&&r==n.target&&l()}),e.on("mouseup keyup",l),e.on("keydown",d)}function a(t){var n=l.length,r=t.content,a=tinymce.trim(o);if("raw"!=t.format){for(;n--;)r=r.replace(l[n],function(t){var n=arguments,i=n[n.length-2];return i>0&&'"'==r.charAt(i-1)?t:''+e.dom.encode("string"==typeof n[1]?n[1]:n[0])+""});t.content=r}}var i,o,l,f=tinymce.dom.TreeWalker,d="contenteditable",u="data-mce-"+d,c=tinymce.util.VK;i=" "+tinymce.trim(e.getParam("noneditable_editable_class","mceEditable"))+" ",o=" "+tinymce.trim(e.getParam("noneditable_noneditable_class","mceNonEditable"))+" ",l=e.getParam("noneditable_regexp"),l&&!l.length&&(l=[l]),e.on("PreInit",function(){r(),l&&e.on("BeforeSetContent",a),e.parser.addAttributeFilter("class",function(e){for(var t,n,r=e.length;r--;)n=e[r],t=" "+n.attr("class")+" ",-1!==t.indexOf(i)?n.attr(u,"true"):-1!==t.indexOf(o)&&n.attr(u,"false")}),e.serializer.addAttributeFilter(u,function(e){for(var t,n=e.length;n--;)t=e[n],l&&t.attr("data-mce-content")?(t.name="#text",t.type=3,t.raw=!0,t.value=t.attr("data-mce-content")):(t.attr(d,null),t.attr(u,null))}),e.parser.addAttributeFilter(d,function(e){for(var t,n=e.length;n--;)t=e[n],t.attr(u,t.attr(d)),t.attr(d,null)})}),e.on("drop",function(e){n(e.target)&&e.preventDefault()})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/pagebreak/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("pagebreak",function(e){var a="mce-pagebreak",t=e.getParam("pagebreak_separator",""),n=new RegExp(t.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(e){return"\\"+e}),"gi"),r='';e.addCommand("mcePageBreak",function(){e.insertContent(e.settings.pagebreak_split_block?"

"+r+"

":r)}),e.addButton("pagebreak",{title:"Page break",cmd:"mcePageBreak"}),e.addMenuItem("pagebreak",{text:"Page break",icon:"pagebreak",cmd:"mcePageBreak",context:"insert"}),e.on("ResolveName",function(t){"IMG"==t.target.nodeName&&e.dom.hasClass(t.target,a)&&(t.name="pagebreak")}),e.on("click",function(t){t=t.target,"IMG"===t.nodeName&&e.dom.hasClass(t,a)&&e.selection.select(t)}),e.on("BeforeSetContent",function(e){e.content=e.content.replace(n,r)}),e.on("PreInit",function(){e.serializer.addNodeFilter("img",function(a){for(var n,r,c=a.length;c--;)if(n=a[c],r=n.attr("class"),r&&-1!==r.indexOf("mce-pagebreak")){var o=n.parent;if(e.schema.getBlockElements()[o.name]&&e.settings.pagebreak_split_block){o.type=3,o.value=t,o.raw=!0,n.remove();continue}n.type=3,n.value=t,n.raw=!0}})})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/preview/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("preview",function(e){var t=e.settings,i=!tinymce.Env.ie;e.addCommand("mcePreview",function(){e.windowManager.open({title:"Preview",width:parseInt(e.getParam("plugin_preview_width","650"),10),height:parseInt(e.getParam("plugin_preview_height","500"),10),html:'",buttons:{text:"Close",onclick:function(){this.parent().parent().close()}},onPostRender:function(){var n,a="";a+='',tinymce.each(e.contentCSS,function(t){a+=''});var r=t.body_id||"tinymce";-1!=r.indexOf("=")&&(r=e.getParam("body_id","","hash"),r=r[e.id]||r);var d=t.body_class||"";-1!=d.indexOf("=")&&(d=e.getParam("body_class","","hash"),d=d[e.id]||"");var o=e.settings.directionality?' dir="'+e.settings.directionality+'"':"";if(n=""+a+'"+e.getContent()+"",i)this.getEl("body").firstChild.src="data:text/html;charset=utf-8,"+encodeURIComponent(n);else{var s=this.getEl("body").firstChild.contentWindow.document;s.open(),s.write(n),s.close()}}})}),e.addButton("preview",{title:"Preview",cmd:"mcePreview"}),e.addMenuItem("preview",{text:"Preview",cmd:"mcePreview",context:"view"})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/print/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("print",function(t){t.addCommand("mcePrint",function(){t.getWin().print()}),t.addButton("print",{title:"Print",cmd:"mcePrint"}),t.addShortcut("Ctrl+P","","mcePrint"),t.addMenuItem("print",{text:"Print",cmd:"mcePrint",icon:"print",shortcut:"Ctrl+P",context:"file"})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/save/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("save",function(e){function a(){var a;return a=tinymce.DOM.getParent(e.id,"form"),!e.getParam("save_enablewhendirty",!0)||e.isDirty()?(tinymce.triggerSave(),e.getParam("save_onsavecallback")?void(e.execCallback("save_onsavecallback",e)&&(e.startContent=tinymce.trim(e.getContent({format:"raw"})),e.nodeChanged())):void(a?(e.isNotDirty=!0,(!a.onsubmit||a.onsubmit())&&("function"==typeof a.submit?a.submit():e.windowManager.alert("Error: Form submit field collision.")),e.nodeChanged()):e.windowManager.alert("Error: No form element found."))):void 0}function n(){var a=tinymce.trim(e.startContent);return e.getParam("save_oncancelcallback")?void e.execCallback("save_oncancelcallback",e):(e.setContent(a),e.undoManager.clear(),void e.nodeChanged())}function t(){var a=this;e.on("nodeChange",function(){a.disabled(e.getParam("save_enablewhendirty",!0)&&!e.isDirty())})}e.addCommand("mceSave",a),e.addCommand("mceCancel",n),e.addButton("save",{icon:"save",text:"Save",cmd:"mceSave",disabled:!0,onPostRender:t}),e.addButton("cancel",{text:"Cancel",icon:!1,cmd:"mceCancel",disabled:!0,onPostRender:t}),e.addShortcut("ctrl+s","","mceSave")}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/tabfocus/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("tabfocus",function(e){function n(e){9!==e.keyCode||e.ctrlKey||e.altKey||e.metaKey||e.preventDefault()}function t(n){function t(n){function t(e){return"BODY"===e.nodeName||"hidden"!=e.type&&"none"!=e.style.display&&"hidden"!=e.style.visibility&&t(e.parentNode)}function r(e){return e.tabIndex||"INPUT"==e.nodeName||"TEXTAREA"==e.nodeName}function c(e){return!r(e)&&"-1"!=e.getAttribute("tabindex")&&t(e)}if(u=i.select(":input:enabled,*[tabindex]:not(iframe)"),o(u,function(n,t){return n.id==e.id?(a=t,!1):void 0}),n>0){for(d=a+1;d=0;d--)if(c(u[d]))return u[d];return null}var a,u,c,d;if(!(9!==n.keyCode||n.ctrlKey||n.altKey||n.metaKey)&&(c=r(e.getParam("tab_focus",e.getParam("tabfocus_elements",":prev,:next"))),1==c.length&&(c[1]=c[0],c[0]=":prev"),u=n.shiftKey?":prev"==c[0]?t(-1):i.get(c[0]):":next"==c[1]?t(1):i.get(c[1]))){var y=tinymce.get(u.id||u.name);u.id&&y?y.focus():window.setTimeout(function(){tinymce.Env.webkit||window.focus(),u.focus()},10),n.preventDefault()}}var i=tinymce.DOM,o=tinymce.each,r=tinymce.explode;e.on("init",function(){e.inline&&tinymce.DOM.setAttrib(e.getBody(),"tabIndex",null)}),e.on("keyup",n),tinymce.Env.gecko?e.on("keypress keydown",t):e.on("keydown",t)}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/template/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("template",function(e){function t(t){return function(){var a=e.settings.templates;"string"==typeof a?tinymce.util.XHR.send({url:a,success:function(e){t(tinymce.util.JSON.parse(e))}}):t(a)}}function a(t){function a(t){function a(t){if(-1==t.indexOf("")){var a="";tinymce.each(e.contentCSS,function(t){a+=''}),t=""+a+""+t+""}t=r(t,"template_preview_replace_values");var l=n.find("iframe")[0].getEl().contentWindow.document;l.open(),l.write(t),l.close()}var c=t.control.value();c.url?tinymce.util.XHR.send({url:c.url,success:function(e){l=e,a(l)}}):(l=c.content,a(l)),n.find("#description")[0].text(t.control.value().description)}var n,l,i=[];return t&&0!==t.length?(tinymce.each(t,function(e){i.push({selected:!i.length,text:e.title,value:{url:e.url,content:e.content,description:e.description}})}),n=e.windowManager.open({title:"Insert template",layout:"flex",direction:"column",align:"stretch",padding:15,spacing:10,items:[{type:"form",flex:0,padding:0,items:[{type:"container",label:"Templates",items:{type:"listbox",label:"Templates",name:"template",values:i,onselect:a}}]},{type:"label",name:"description",label:"Description",text:" "},{type:"iframe",flex:1,border:1}],onsubmit:function(){c(!1,l)},width:e.getParam("template_popup_width",600),height:e.getParam("template_popup_height",500)}),void n.find("listbox")[0].fire("select")):void e.windowManager.alert("No templates defined")}function n(t,a){function n(e,t){if(e=""+e,e.length0&&(o=p.create("div",null),o.appendChild(s[0].cloneNode(!0))),i(p.select("*",o),function(t){c(t,e.getParam("template_cdate_classes","cdate").replace(/\s+/g,"|"))&&(t.innerHTML=n(e.getParam("template_cdate_format",e.getLang("template.cdate_format")))),c(t,e.getParam("template_mdate_classes","mdate").replace(/\s+/g,"|"))&&(t.innerHTML=n(e.getParam("template_mdate_format",e.getLang("template.mdate_format")))),c(t,e.getParam("template_selected_content_classes","selcontent").replace(/\s+/g,"|"))&&(t.innerHTML=m)}),l(o),e.execCommand("mceInsertContent",!1,o.innerHTML),e.addVisual()}var i=tinymce.each;e.addCommand("mceInsertTemplate",c),e.addButton("template",{title:"Insert template",onclick:t(a)}),e.addMenuItem("template",{text:"Insert template",onclick:t(a),context:"insert"}),e.on("PreProcess",function(t){var a=e.dom;i(a.select("div",t.node),function(t){a.hasClass(t,"mceTmpl")&&(i(a.select("*",t),function(t){a.hasClass(t,e.getParam("template_mdate_classes","mdate").replace(/\s+/g,"|"))&&(t.innerHTML=n(e.getParam("template_mdate_format",e.getLang("template.mdate_format"))))}),l(t))})})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/textcolor/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("textcolor",function(t){function e(e){var o;return t.dom.getParents(t.selection.getStart(),function(t){var r;(r=t.style["forecolor"==e?"color":"background-color"])&&(o=r)}),o}function o(){var e,o,r=[];for(o=t.settings.textcolor_map||["000000","Black","993300","Burnt orange","333300","Dark olive","003300","Dark green","003366","Dark azure","000080","Navy Blue","333399","Indigo","333333","Very dark gray","800000","Maroon","FF6600","Orange","808000","Olive","008000","Green","008080","Teal","0000FF","Blue","666699","Grayish blue","808080","Gray","FF0000","Red","FF9900","Amber","99CC00","Yellow green","339966","Sea green","33CCCC","Turquoise","3366FF","Royal blue","800080","Purple","999999","Medium gray","FF00FF","Magenta","FFCC00","Gold","FFFF00","Yellow","00FF00","Lime","00FFFF","Aqua","00CCFF","Sky blue","993366","Red violet","FFFFFF","White","FF99CC","Pink","FFCC99","Peach","FFFF99","Light yellow","CCFFCC","Pale green","CCFFFF","Pale cyan","99CCFF","Light sky blue","CC99FF","Plum"],e=0;e
'+(o?"×":"")+"
"}var r,l,a,n,c,d,u,g=this,m=g._id,F=0;for(r=o(),r.push({text:tinymce.translate("No color"),color:"transparent"}),a='',n=r.length-1,d=0;s>d;d++){for(a+="",c=0;i>c;c++)u=d*i+c,u>n?a+="":(l=r[u],a+=e(l.color,l.text));a+=""}if(t.settings.color_picker_callback){for(a+='",a+="",c=0;i>c;c++)a+=e("","Custom color");a+=""}return a+="
"}function l(e,o){t.focus(),t.formatter.apply(e,{value:o}),t.nodeChanged()}function a(e){t.focus(),t.formatter.remove(e,{value:null},null,!0),t.nodeChanged()}function n(o){function r(t){s.hidePanel(),s.color(t),l(s.settings.format,t)}function n(t,e){t.style.background=e,t.setAttribute("data-mce-color",e)}var c,s=this.parent();if(tinymce.DOM.getParent(o.target,".mce-custom-color-btn")&&(s.hidePanel(),t.settings.color_picker_callback.call(t,function(t){var e,o,l,a=s.panel.getEl().getElementsByTagName("table")[0];for(e=tinymce.map(a.rows[a.rows.length-1].childNodes,function(t){return t.firstChild}),l=0;ll;l++)n(e[l],e[l+1].getAttribute("data-mce-color"));n(o,t),r(t)},e(s.settings.format))),c=o.target.getAttribute("data-mce-color")){if(this.lastId&&document.getElementById(this.lastId).setAttribute("aria-selected",!1),o.target.setAttribute("aria-selected",!0),this.lastId=o.target.id,"transparent"==c)return a(s.settings.format),void s.hidePanel();r(c)}else null!==c&&s.hidePanel()}function c(){var t=this;t._color&&l(t.settings.format,t._color)}var i,s;s=t.settings.textcolor_rows||5,i=t.settings.textcolor_cols||8,t.addButton("forecolor",{type:"colorbutton",tooltip:"Text color",format:"forecolor",panel:{role:"application",ariaRemember:!0,html:r,onclick:n},onclick:c}),t.addButton("backcolor",{type:"colorbutton",tooltip:"Background color",format:"hilitecolor",panel:{role:"application",ariaRemember:!0,html:r,onclick:n},onclick:c})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/textpattern/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("textpattern",function(t){function e(){return l&&(i.sort(function(t,e){return t.start.length>e.start.length?-1:t.start.length$1
'),c=e.dom.create("div",null,r);t=c.lastChild;)e.dom.insertAfter(t,s[i]);e.dom.remove(s[i])}else for(s=e.dom.select("span.mce-nbsp",l),i=s.length-1;i>=0;i--)e.dom.remove(s[i],1);m.moveToBookmark(d)}function t(){var a=this;e.on("VisualChars",function(e){a.active(e.state)})}var n,o=this;e.addCommand("mceVisualChars",a),e.addButton("visualchars",{title:"Show invisible characters",cmd:"mceVisualChars",onPostRender:t}),e.addMenuItem("visualchars",{text:"Show invisible characters",cmd:"mceVisualChars",onPostRender:t,selectable:!0,context:"view",prependToContext:!0}),e.on("beforegetcontent",function(e){n&&"raw"!=e.format&&!e.draft&&(n=!0,a(!1))})}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/plugins/wordcount/plugin.min.js: -------------------------------------------------------------------------------- 1 | tinymce.PluginManager.add("wordcount",function(e){function t(){e.theme.panel.find("#wordcount").text(["Words: {0}",a.getCount()])}var n,o,a=this;n=e.getParam("wordcount_countregex",/[\w\u2019\x27\-\u00C0-\u1FFF]+/g),o=e.getParam("wordcount_cleanregex",/[0-9.(),;:!?%#$?\x27\x22_+=\\\/\-]*/g),e.on("init",function(){var n=e.theme.panel&&e.theme.panel.find("#statusbar")[0];n&&window.setTimeout(function(){n.insert({type:"label",name:"wordcount",text:["Words: {0}",a.getCount()],classes:"wordcount",disabled:e.settings.readonly},0),e.on("setcontent beforeaddundo",t),e.on("keyup",function(e){32==e.keyCode&&t()})},0)}),a.getCount=function(){var t=e.getContent({format:"raw"}),a=0;if(t){t=t.replace(/\.\.\./g," "),t=t.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," "),t=t.replace(/(\w+)(&#?[a-z0-9]+;)+(\w+)/i,"$1$3").replace(/&.+?;/g," "),t=t.replace(o,"");var r=t.match(n);r&&(a=r.length)}return a}}); -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/content.inline.min.css: -------------------------------------------------------------------------------- 1 | .mce-object{border:1px dotted #3A3A3A;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0px}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp{background:#AAA}hr{cursor:default}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td.mce-item-selected,th.mce-item-selected{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333} -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/content.min.css: -------------------------------------------------------------------------------- 1 | body{background-color:#FFFFFF;color:#000000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px;scrollbar-3dlight-color:#F0F0EE;scrollbar-arrow-color:#676662;scrollbar-base-color:#F0F0EE;scrollbar-darkshadow-color:#DDDDDD;scrollbar-face-color:#E0E0DD;scrollbar-highlight-color:#F0F0EE;scrollbar-shadow-color:#F0F0EE;scrollbar-track-color:#F5F5F5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:11px}.mce-object{border:1px dotted #3A3A3A;background:#d5d5d5 url(img/object.gif) no-repeat center}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0px}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#d5d5d5 url(img/anchor.gif) no-repeat center}.mce-nbsp{background:#AAA}hr{cursor:default}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td.mce-item-selected,th.mce-item-selected{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333} -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/fonts/readme.md: -------------------------------------------------------------------------------- 1 | Icons are generated and provided by the http://icomoon.io service. 2 | -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.eot -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.ttf -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/tinymce/js/tinymce/skins/lightgray/fonts/tinymce-small.woff -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.eot -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.ttf -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/tinymce/js/tinymce/skins/lightgray/fonts/tinymce.woff -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/img/anchor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/tinymce/js/tinymce/skins/lightgray/img/anchor.gif -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/img/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/tinymce/js/tinymce/skins/lightgray/img/loader.gif -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/img/object.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/tinymce/js/tinymce/skins/lightgray/img/object.gif -------------------------------------------------------------------------------- /public/tinymce/js/tinymce/skins/lightgray/img/trans.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/averna-syd/LibreMailer/17723a1da1e4aa407b64d69184a56220501c13f2/public/tinymce/js/tinymce/skins/lightgray/img/trans.gif -------------------------------------------------------------------------------- /t/001_base.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 11; 2 | use strict; 3 | use warnings; 4 | 5 | use_ok 'LibreMailer'; 6 | use_ok 'LibreMailer::EncodeSafeURL'; 7 | use_ok 'LibreMailer::DateTime'; 8 | use_ok 'LibreMailer::Tracker'; 9 | use_ok 'LibreMailer::Contacts'; 10 | use_ok 'LibreMailer::Lists'; 11 | use_ok 'LibreMailer::Users'; 12 | use_ok 'LibreMailer::Roles'; 13 | use_ok 'LibreMailer::Campaigns'; 14 | use_ok 'LibreMailer::Statistics'; 15 | use_ok 'LibreMailer::Worker'; 16 | -------------------------------------------------------------------------------- /t/002_index.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 5; 2 | use strict; 3 | use warnings; 4 | 5 | # the order is important 6 | use LibreMailer::RestClient; 7 | use Dancer::Test; 8 | use JSON::Any; 9 | use Data::Dumper; 10 | 11 | my $j = JSON::Any->new; 12 | my $client = LibreMailer::RestClient->new( host => 'http://localhost:3000' ); 13 | my $url = '/login'; 14 | my $data = { username => 'admin', password => 'admin' }; 15 | 16 | my ( $code, $response ) = $client->request( 'POST', $url, $j->to_json( $data ) ); 17 | ok ( $code eq '200', "response expected: 200 response given: $code for POST $url" ); 18 | 19 | $url = '/'; 20 | ( $code, $response ) = $client->request( 'GET', $url ); 21 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 22 | 23 | $url = '/denied'; 24 | ( $code, $response ) = $client->request( 'GET', $url ); 25 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 26 | 27 | $url = '/logout'; 28 | ( $code, $response) = $client->request( 'GET', $url ); 29 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 30 | 31 | $url = '/login'; 32 | ( $code, $response) = $client->request( 'GET', $url ); 33 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 34 | 35 | -------------------------------------------------------------------------------- /t/003_campaigns.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 5; 2 | use strict; 3 | use warnings; 4 | 5 | # the order is important 6 | use LibreMailer::RestClient; 7 | use Dancer::Test; 8 | use JSON::Any; 9 | use Data::Dumper; 10 | 11 | my $j = JSON::Any->new; 12 | my $client = LibreMailer::RestClient->new( host => 'http://localhost:3000' ); 13 | my $url = '/login'; 14 | my $data = { username => 'admin', password => 'admin' }; 15 | 16 | my ( $code, $response ) = $client->request( 'POST', $url, $j->to_json( $data ) ); 17 | ok ( $code eq '200', "response expected: 200 response given: $code for POST $url" ); 18 | 19 | $url = '/campaigns'; 20 | ( $code, $response ) = $client->request( 'GET', $url ); 21 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 22 | 23 | $url = '/campaigns/add'; 24 | ( $code, $response ) = $client->request( 'GET', $url ); 25 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 26 | 27 | $url = '/campaigns/edit/1'; 28 | ( $code, $response) = $client->request( 'GET', $url ); 29 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 30 | 31 | $url = '/campaigns/delete/1'; 32 | ( $code, $response) = $client->request( 'GET', $url ); 33 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 34 | -------------------------------------------------------------------------------- /t/004_contacts.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 5; 2 | use strict; 3 | use warnings; 4 | 5 | # the order is important 6 | use LibreMailer::RestClient; 7 | use Dancer::Test; 8 | use JSON::Any; 9 | use Data::Dumper; 10 | 11 | my $j = JSON::Any->new; 12 | my $client = LibreMailer::RestClient->new( host => 'http://localhost:3000' ); 13 | my $url = '/login'; 14 | my $data = { username => 'admin', password => 'admin' }; 15 | 16 | my ( $code, $response ) = $client->request( 'POST', $url, $j->to_json( $data ) ); 17 | ok ( $code eq '200', "response expected: 200 response given: $code for POST $url" ); 18 | 19 | $url = '/contacts'; 20 | ( $code, $response ) = $client->request( 'GET', $url ); 21 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 22 | 23 | $url = '/contacts/add'; 24 | ( $code, $response ) = $client->request( 'GET', $url ); 25 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 26 | 27 | $url = '/contacts/edit/1'; 28 | ( $code, $response) = $client->request( 'GET', $url ); 29 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 30 | 31 | $url = '/contacts/delete/1'; 32 | ( $code, $response) = $client->request( 'GET', $url ); 33 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 34 | 35 | -------------------------------------------------------------------------------- /t/005_lists.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 5; 2 | use strict; 3 | use warnings; 4 | 5 | # the order is important 6 | use LibreMailer::RestClient; 7 | use Dancer::Test; 8 | use JSON::Any; 9 | use Data::Dumper; 10 | 11 | my $j = JSON::Any->new; 12 | my $client = LibreMailer::RestClient->new( host => 'http://localhost:3000' ); 13 | my $url = '/login'; 14 | my $data = { username => 'admin', password => 'admin' }; 15 | 16 | my ( $code, $response ) = $client->request( 'POST', $url, $j->to_json( $data ) ); 17 | ok ( $code eq '200', "response expected: 200 response given: $code for POST $url" ); 18 | 19 | $url = '/lists'; 20 | ( $code, $response ) = $client->request( 'GET', $url ); 21 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 22 | 23 | $url = '/lists/add'; 24 | ( $code, $response ) = $client->request( 'GET', $url ); 25 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 26 | 27 | $url = '/lists/edit/1'; 28 | ( $code, $response) = $client->request( 'GET', $url ); 29 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 30 | 31 | $url = '/lists/delete/1'; 32 | ( $code, $response) = $client->request( 'GET', $url ); 33 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 34 | 35 | -------------------------------------------------------------------------------- /t/006_roles.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 5; 2 | use strict; 3 | use warnings; 4 | 5 | # the order is important 6 | use LibreMailer::RestClient; 7 | use Dancer::Test; 8 | use JSON::Any; 9 | use Data::Dumper; 10 | 11 | my $j = JSON::Any->new; 12 | my $client = LibreMailer::RestClient->new( host => 'http://localhost:3000' ); 13 | my $url = '/login'; 14 | my $data = { username => 'admin', password => 'admin' }; 15 | 16 | my ( $code, $response ) = $client->request( 'POST', $url, $j->to_json( $data ) ); 17 | ok ( $code eq '200', "response expected: 200 response given: $code for POST $url" ); 18 | 19 | $url = '/roles'; 20 | ( $code, $response ) = $client->request( 'GET', $url ); 21 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 22 | 23 | $url = '/roles/add'; 24 | ( $code, $response ) = $client->request( 'GET', $url ); 25 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 26 | 27 | $url = '/roles/edit/1'; 28 | ( $code, $response) = $client->request( 'GET', $url ); 29 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 30 | 31 | $url = '/roles/delete/1'; 32 | ( $code, $response) = $client->request( 'GET', $url ); 33 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 34 | 35 | -------------------------------------------------------------------------------- /t/007_statistics.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 5; 2 | use strict; 3 | use warnings; 4 | 5 | # the order is important 6 | use LibreMailer::RestClient; 7 | use Dancer::Test; 8 | use JSON::Any; 9 | use Data::Dumper; 10 | 11 | my $j = JSON::Any->new; 12 | my $client = LibreMailer::RestClient->new( host => 'http://localhost:3000' ); 13 | my $url = '/login'; 14 | my $data = { username => 'admin', password => 'admin' }; 15 | 16 | my ( $code, $response ) = $client->request( 'POST', $url, $j->to_json( $data ) ); 17 | ok ( $code eq '200', "response expected: 200 response given: $code for POST $url" ); 18 | 19 | $url = '/statistics'; 20 | ( $code, $response ) = $client->request( 'GET', $url ); 21 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 22 | 23 | $url = '/statistics/add'; 24 | ( $code, $response ) = $client->request( 'GET', $url ); 25 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 26 | 27 | $url = '/statistics/edit/1'; 28 | ( $code, $response) = $client->request( 'GET', $url ); 29 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 30 | 31 | $url = '/statistics/delete/1'; 32 | ( $code, $response) = $client->request( 'GET', $url ); 33 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 34 | 35 | -------------------------------------------------------------------------------- /t/008_users.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 5; 2 | use strict; 3 | use warnings; 4 | 5 | # the order is important 6 | use LibreMailer::RestClient; 7 | use Dancer::Test; 8 | use JSON::Any; 9 | use Data::Dumper; 10 | 11 | my $j = JSON::Any->new; 12 | my $client = LibreMailer::RestClient->new( host => 'http://localhost:3000' ); 13 | my $url = '/login'; 14 | my $data = { username => 'admin', password => 'admin' }; 15 | 16 | my ( $code, $response ) = $client->request( 'POST', $url, $j->to_json( $data ) ); 17 | ok ( $code eq '200', "response expected: 200 response given: $code for POST $url" ); 18 | 19 | $url = '/users'; 20 | ( $code, $response ) = $client->request( 'GET', $url ); 21 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 22 | 23 | $url = '/users/add'; 24 | ( $code, $response ) = $client->request( 'GET', $url ); 25 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 26 | 27 | $url = '/users/edit/1'; 28 | ( $code, $response) = $client->request( 'GET', $url ); 29 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 30 | 31 | $url = '/users/delete/1'; 32 | ( $code, $response) = $client->request( 'GET', $url ); 33 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 34 | 35 | -------------------------------------------------------------------------------- /t/009_datetime.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 5; 2 | use strict; 3 | use warnings; 4 | 5 | # the order is important 6 | use Dancer::Test; 7 | use JSON::Any; 8 | use Data::Dumper; 9 | 10 | use LibreMailer::DateTime; 11 | 12 | ok( my $datetime = LibreMailer::DateTime->new, 'New obj' ); 13 | 14 | isa_ok( $datetime, 'LibreMailer::DateTime' ); 15 | 16 | ok( my $dt = $datetime->current_datetime, 'current_datetime' ); 17 | 18 | ok( my $sql_dt = $datetime->sql_current_datetime, 'sql_current_datetime' ); 19 | 20 | ok( $datetime->convert_sqlt_to_dt( $sql_dt ), 'convert_sqlt_to_dt' ); 21 | 22 | ok( $datetime->convert_dt_to_sqlt( $dt ), 'convert_dt_to_sqlt' ); 23 | 24 | ok( $datetime->check_schedule( $sql_dt ), 'check_schedule' ); 25 | -------------------------------------------------------------------------------- /t/010_encode_safe_url.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 4; 2 | use strict; 3 | use warnings; 4 | 5 | # the order is important 6 | use Dancer::Test; 7 | use JSON::Any; 8 | use Data::Dumper; 9 | 10 | use LibreMailer::EncodeSafeURL; 11 | 12 | ok( my $encode = LibreMailer::EncodeSafeURL->new, 'New obj' ); 13 | 14 | isa_ok( $encode, 'LibreMailer::EncodeSafeURL' ); 15 | 16 | ok( my $string = $encode->encrypt_sting( 'hello' ), 'encrypt_sting' ); 17 | 18 | ok( $encode->decrypt_string( $string ), 'decrypt_string' ); 19 | -------------------------------------------------------------------------------- /t/011_worker.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 2; 2 | use strict; 3 | use warnings; 4 | 5 | # the order is important 6 | use Dancer::Test; 7 | use JSON::Any; 8 | use Data::Dumper; 9 | 10 | use LibreMailer::Worker; 11 | 12 | ok( my $worker = LibreMailer::Worker->new, 'New obj' ); 13 | 14 | isa_ok( $worker, 'LibreMailer::Worker' ); 15 | -------------------------------------------------------------------------------- /t/012_tracker.t: -------------------------------------------------------------------------------- 1 | use Test::More tests => 5; 2 | use strict; 3 | use warnings; 4 | 5 | # the order is important 6 | use LibreMailer::RestClient; 7 | use Dancer::Test; 8 | use JSON::Any; 9 | use Data::Dumper; 10 | 11 | my $j = JSON::Any->new; 12 | my $client = LibreMailer::RestClient->new( host => 'http://localhost:3000' ); 13 | my $url = '/login'; 14 | my $data = { username => 'admin', password => 'admin' }; 15 | 16 | my ( $code, $response ) = $client->request( 'POST', $url, $j->to_json( $data ) ); 17 | ok ( $code eq '200', "response expected: 200 response given: $code for POST $url" ); 18 | 19 | $url = '/t/open/U2FsdGVkX1-zXWiQRWvd1c2VGQuS2OR_/U2FsdGVkX19eXy0Eb0oPKBuEG5uzP_4c/open.gif'; 20 | ( $code, $response ) = $client->request( 'GET', $url ); 21 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 22 | 23 | $url = '/t/link/U2FsdGVkX1-zXWiQRWvd1c2VGQuS2OR_/U2FsdGVkX19eXy0Eb0oPKBuEG5uzP_4c/U2FsdGVkX18ni-FQHhU2NaIfaP0mqyOd'; 24 | ( $code, $response ) = $client->request( 'GET', $url ); 25 | ok ( $code eq '302', "response expected: 200 response given: $code for GET $url" ); 26 | 27 | $url = '/t/viewonline/U2FsdGVkX1-zXWiQRWvd1c2VGQuS2OR_/U2FsdGVkX19eXy0Eb0oPKBuEG5uzP_4c'; 28 | ( $code, $response) = $client->request( 'GET', $url ); 29 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 30 | 31 | $url = '/t/unsubscribe/U2FsdGVkX1-zXWiQRWvd1c2VGQuS2OR_/U2FsdGVkX19eXy0Eb0oPKBuEG5uzP_4c'; 32 | ( $code, $response) = $client->request( 'GET', $url ); 33 | ok ( $code eq '200', "response expected: 200 response given: $code for GET $url" ); 34 | -------------------------------------------------------------------------------- /uploads/readme.txt: -------------------------------------------------------------------------------- 1 | Uploads go here. YAY! \0/ 2 | -------------------------------------------------------------------------------- /views/404.tt: -------------------------------------------------------------------------------- 1 |

404 Page not found

2 |
3 | Mistakes are the portals of discovery. However in this instance, I think we might be out of luck. 4 | -------------------------------------------------------------------------------- /views/campaigns.tt: -------------------------------------------------------------------------------- 1 |

Campaigns

2 |
3 | [% simple_crud %] 4 | 5 | 10 | 30 | -------------------------------------------------------------------------------- /views/contacts.tt: -------------------------------------------------------------------------------- 1 |

Contacts

2 |
3 | [% simple_crud %] 4 | -------------------------------------------------------------------------------- /views/data/readme.txt: -------------------------------------------------------------------------------- 1 | campaign templates go here after launch. 2 | -------------------------------------------------------------------------------- /views/denied.tt: -------------------------------------------------------------------------------- 1 |

Denied

2 |
3 | [% IF session.denied_msg %] 4 |

[% session.denied_msg %]

5 | [% ELSE %] 6 |

I'm sorry [% session.firstname %], I'm afraid I can't do that, I think you know what the problem is just as well as I do. Please contact your administrator if you require assistance.

7 | [% END %] 8 |

It might be best to try the home page.

9 | -------------------------------------------------------------------------------- /views/index.tt: -------------------------------------------------------------------------------- 1 |

Project feature tracker

2 |
3 | 4 |
5 |

Title

6 |
7 | [% form.as_p %] 8 | 9 | 10 |
11 |
12 | -------------------------------------------------------------------------------- /views/lists.tt: -------------------------------------------------------------------------------- 1 |

Lists

2 |
3 | 4 | [% simple_crud %] 5 | -------------------------------------------------------------------------------- /views/login.tt: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 26 |
27 |
28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /views/report.tt: -------------------------------------------------------------------------------- 1 |

Report Statistics for [% stats.campaign_name %]

2 |
3 |

4 |

Open Statistics

5 |
6 |
7 | 8 |
9 |
10 |

Opened: [% opens.opened %]    Unopened: [% opens.unopened %]    Bounced: [% opens.bounced %]

11 |

12 |

Link Statistics

13 |
14 |
15 | 16 |
17 |
18 |

[% FOREACH link IN links %][% link.name %]: [% link.count %]    [% END %]

19 | 20 | 70 | -------------------------------------------------------------------------------- /views/roles.tt: -------------------------------------------------------------------------------- 1 |

Roles

2 |
3 | [% simple_crud %] 4 | -------------------------------------------------------------------------------- /views/statistics.tt: -------------------------------------------------------------------------------- 1 |

Statistics

2 |
3 | [% simple_crud %] 4 | -------------------------------------------------------------------------------- /views/statistics_bounces.tt: -------------------------------------------------------------------------------- 1 |

Bounce Statistics

2 |
3 | [% simple_crud %] 4 | -------------------------------------------------------------------------------- /views/statistics_links.tt: -------------------------------------------------------------------------------- 1 |

Link Statistics

2 |
3 | [% simple_crud %] 4 | -------------------------------------------------------------------------------- /views/statistics_opens.tt: -------------------------------------------------------------------------------- 1 |

Open Statistics

2 |
3 | [% simple_crud %] 4 | -------------------------------------------------------------------------------- /views/statistics_unsubscribes.tt: -------------------------------------------------------------------------------- 1 |

Unsubscribes Statistics

2 |
3 | [% simple_crud %] 4 | -------------------------------------------------------------------------------- /views/unsubscribe.tt: -------------------------------------------------------------------------------- 1 |

Unsubscribe

2 |
3 |

You have been successfully unsubscribed.

4 | -------------------------------------------------------------------------------- /views/upload.tt: -------------------------------------------------------------------------------- 1 |

Upload Contacts to a Contact List

2 |
3 | 4 |
5 |

Required fields in CSV file: "email", "firstname", "lastname".

6 |

Optional fields in CSV file: "format", "confirmation", "status".

7 |

8 | Field "format" default is "HTML" but accepts inputs: "HTML", "Text".
9 | Field "confirmation" default is "Confirmed" but accepts inputs: "Confirmed", "Unconfirmed".
10 | Field "status" default is "Active" but accepts inputs: "Active", "Unsubscribed", "Bounced".
11 |

12 |

Fields that are highlighted are required.

13 | 14 | 15 | 16 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
Contact List 17 | 23 |
CSV File
33 |
34 | -------------------------------------------------------------------------------- /views/users.tt: -------------------------------------------------------------------------------- 1 |

Users

2 |
3 | [% simple_crud %] 4 | --------------------------------------------------------------------------------