diff --git a/.env b/.env index 1034f2d82..832d947ee 100644 --- a/.env +++ b/.env @@ -4,7 +4,7 @@ APP_KEY=SomeRandomString DB_TYPE=mysql DB_HOST=localhost DB_PORT= -DB_DATABASE=faveo +DB_DATABASE=faveo-dev DB_USERNAME=root DB_PASSWORD= MAIL_DRIVER=smtp diff --git a/README.md b/README.md index b6b65ba5c..cba2aadbd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

About Faveo

+

About Faveo


   StyleCI  

Headquartered in Bangalore, Faveo HELPDESK provides Businesses with an automated Helpdesk system to manage customer support.

diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 202e877e9..71bc33099 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -9,6 +9,8 @@ use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; class Handler extends ExceptionHandler { + public $phpmailer; + /** * A list of the exception types that should not be reported. * @@ -18,18 +20,6 @@ class Handler extends ExceptionHandler 'Symfony\Component\HttpKernel\Exception\HttpException', ]; - /** - * Create a new controller instance. - * constructor to check - * 1. php mailer. - * - * @return void - */ - // public function __construct(PhpMailController $PhpMailController) - // { - // $this->PhpMailController = $PhpMailController; - // } - /** * Report or log an exception. * @@ -54,30 +44,34 @@ class Handler extends ExceptionHandler */ public function render($request, Exception $e) { - // $phpmail = new PhpMailController; -// if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException) { -// return response()->json(['message' => $e->getMessage(), 'code' => $e->getStatusCode()]); -// } elseif ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException) { -// return response()->json(['message' => $e->getMessage(), 'code' => $e->getStatusCode()]); -// } -// // This is to check if the debug is true or false -// if (config('app.debug') == false) { -// // checking if the error is actually an error page or if its an system error page -// if ($this->isHttpException($e) && $e->getStatusCode() == 404) { -// return response()->view('errors.404', []); -// } else { -// // checking if the application is installed -// if (\Config::get('database.install') == 1) { -// // checking if the error log send to Ladybirdweb is enabled or not -// if (\Config::get('app.ErrorLog') == '1') { -// $this->phpmail->sendmail($from = $this->PhpMailController->mailfrom('1', '0'), $to = ['name' => 'faveo logger', 'email' => 'faveoerrorlogger@gmail.com'], $message = ['subject' => 'Faveo downloaded from github has occured error', 'scenario' => 'error-report'], $template_variables = ['e' => $e]); -// } -// } -// -// return response()->view('errors.500', []); -// } -// } -// // returns non oops error message + //dd($e); + $phpmail = new PhpMailController(); + $this->PhpMailController = $phpmail; + if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException) { + return response()->json(['message' => $e->getMessage(), 'code' => $e->getStatusCode()]); + } elseif ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException) { + return response()->json(['message' => $e->getMessage(), 'code' => $e->getStatusCode()]); + } + // This is to check if the debug is true or false + if (config('app.debug') == false) { + // checking if the error is actually an error page or if its an system error page + if ($this->isHttpException($e) && $e->getStatusCode() == 404) { + return response()->view('errors.404', []); + } else { + // checking if the application is installed + if (\Config::get('database.install') == 1) { + // checking if the error log send to Ladybirdweb is enabled or not + if (\Config::get('app.ErrorLog') == '1') { + try { + $this->PhpMailController->sendmail($from = $this->PhpMailController->mailfrom('1', '0'), $to = ['name' => 'faveo logger', 'email' => 'faveoerrorlogger@gmail.com'], $message = ['subject' => 'Faveo downloaded from github has occured error', 'scenario' => 'error-report'], $template_variables = ['system_error' => "

 Message:".$e->getMessage().'
Code:'.$e->getCode().'
File:'.$e->getFile().'
Line:'.$e->getLine().'
']); + } catch (Exception $exx) { + } + } + } + return response()->view('errors.500', []); + } + } + // returns non oops error message return parent::render($request, $e); // checking if the error is related to http error i.e. page not found if ($this->isHttpException($e)) { diff --git a/app/Http/Controllers/Admin/helpdesk/AgentController.php b/app/Http/Controllers/Admin/helpdesk/AgentController.php index eb16521bf..202e83ecd 100644 --- a/app/Http/Controllers/Admin/helpdesk/AgentController.php +++ b/app/Http/Controllers/Admin/helpdesk/AgentController.php @@ -107,7 +107,8 @@ class AgentController extends Controller // fixing the user role to agent $user->fill($request->input())->save(); // generate password and has immediately to store - $user->password = Hash::make($this->generateRandomString()); + $password = $this->generateRandomString(); + $user->password = Hash::make($password); // fetching all the team details checked for this user $requests = $request->input('team_id'); // get user id of the inserted user detail @@ -127,7 +128,7 @@ class AgentController extends Controller $this->PhpMailController->sendmail($from = $this->PhpMailController->mailfrom('1', '0'), $to = ['name' => $name, 'email' => $email], $message = ['subject' => 'Password', 'scenario' => 'registration-notification'], $template_variables = ['user' => $name, 'email_address' => $email, 'user_password' => $password]); } catch (Exception $e) { // returns if try fails - return redirect('agents')->with('fails', 'Some error occured while sending mail to the agent. Please check email settings and try again'); + return redirect('agents')->with('fails', 'Some error occurred while sending mail to the agent. Please check email settings and try again'); } // returns for the success case return redirect('agents')->with('success', 'Agent Created sucessfully'); diff --git a/app/Http/Controllers/Admin/helpdesk/EmailsController.php b/app/Http/Controllers/Admin/helpdesk/EmailsController.php index c639b5388..c68bd7356 100644 --- a/app/Http/Controllers/Admin/helpdesk/EmailsController.php +++ b/app/Http/Controllers/Admin/helpdesk/EmailsController.php @@ -19,8 +19,6 @@ use Crypt; use Exception; use Illuminate\Http\Request; -//use PhpImap\Mailbox as ImapMailbox; - /** * ====================================== * EmailsController. @@ -120,9 +118,14 @@ class EmailsController extends Controller return $return_data; } + if ($request->validate == 'on') { + $validate = '/validate-cert'; + } else { + $validate = '/novalidate-cert'; + } if ($request->fetching_status == 'on') { - $imap_check = $this->getImapStream($request); - if ($imap_check == 0) { + $imap_check = $this->getImapStream($request, $validate); + if ($imap_check[0] == 0) { return 'Incoming email connection failed'; } $need_to_check_imap = 1; @@ -143,17 +146,17 @@ class EmailsController extends Controller if ($need_to_check_imap == 1 && $need_to_check_smtp == 1) { if ($imap_check != 0 && $smtp_check != 0) { - $this->store($request); + $this->store($request, $imap_check[1]); $return = 1; } } elseif ($need_to_check_imap == 1 && $need_to_check_smtp == 0) { if ($imap_check != 0 && $smtp_check == 0) { - $this->store($request); + $this->store($request, $imap_check[1]); $return = 1; } } elseif ($need_to_check_imap == 0 && $need_to_check_smtp == 1) { if ($imap_check == 0 && $smtp_check != 0) { - $this->store($request); + $this->store($request, null); $return = 1; } } elseif ($need_to_check_imap == 0 && $need_to_check_smtp == 0) { @@ -174,14 +177,14 @@ class EmailsController extends Controller * * @return type Redirect */ - public function store($request) + public function store($request, $imap_check) { // dd($request); $email = new Emails(); try { // getConnection($request->input('email_name'), $request->input('email_address'), $request->input('email_address')) // saving all the fields to the database - if ($email->fill($request->except('password', 'department', 'priority', 'help_topic', 'fetching_status', 'sending_status', 'auto_response'))->save() == true) { + if ($email->fill($request->except('password', 'department', 'priority', 'help_topic', 'fetching_status', 'fetching_encryption', 'sending_status', 'auto_response'))->save() == true) { if ($request->fetching_status == 'on') { $email->fetching_status = 1; } else { @@ -197,7 +200,12 @@ class EmailsController extends Controller } else { $email->auto_response = 0; } - // fetching department value + if ($imap_check !== null) { + $email->fetching_encryption = $imap_check; + } else { + $email->fetching_encryption = $request->fetching_encryption; + } + // fetching department value $email->department = $this->departmentValue($request->input('department')); // fetching priority value $email->priority = $this->priorityValue($request->input('priority')); @@ -289,8 +297,13 @@ class EmailsController extends Controller return $return_data; } // return $request; + if ($request->validate == 'on') { + $validate = '/validate-cert'; + } else { + $validate = '/novalidate-cert'; + } if ($request->fetching_status == 'on') { - $imap_check = $this->getImapStream($request); + $imap_check = $this->getImapStream($request, $validate); if ($imap_check == 0) { return 'Incoming email connection failed'; } @@ -425,7 +438,7 @@ class EmailsController extends Controller * * @return type int */ - public function getImapStream($request) + public function getImapStream($request, $validate) { $fetching_status = $request->input('fetching_status'); $username = $request->input('email_address'); @@ -433,13 +446,20 @@ class EmailsController extends Controller $protocol_id = $request->input('mailbox_protocol'); $fetching_protocol = '/'.$request->input('fetching_protocol'); $fetching_encryption = '/'.$request->input('fetching_encryption'); - if ($fetching_encryption == 'none') { - $fetching_encryption = 'novalidate-cert'; + if ($fetching_encryption == '/none') { + $fetching_encryption2 = '/novalidate-cert'; + $mailbox_protocol = $fetching_encryption2; + $host = $request->input('fetching_host'); + $port = $request->input('fetching_port'); + $mailbox = '{'.$host.':'.$port.$mailbox_protocol.'}INBOX'; + } else { + $mailbox_protocol = $fetching_protocol.$fetching_encryption; + $host = $request->input('fetching_host'); + $port = $request->input('fetching_port'); + $mailbox = '{'.$host.':'.$port.$mailbox_protocol.$validate.'}INBOX'; + $mailbox_protocol = $fetching_encryption.$validate; } - $mailbox_protocol = $fetching_protocol.$fetching_encryption; - $host = $request->input('fetching_host'); - $port = $request->input('fetching_port'); - $mailbox = '{'.$host.':'.$port.$mailbox_protocol.'}INBOX'; + try { $imap_stream = imap_open($mailbox, $username, $password); } catch (\Exception $ex) { @@ -447,9 +467,9 @@ class EmailsController extends Controller } $imap_stream = imap_open($mailbox, $username, $password); if ($imap_stream) { - $return = 1; + $return = [0 => 1, 1 => $mailbox_protocol]; } else { - $return = 0; + $return = [0 => 0]; } return $return; diff --git a/app/Http/Controllers/Admin/helpdesk/GroupController.php b/app/Http/Controllers/Admin/helpdesk/GroupController.php index 9e8392cc7..a89bc1cfb 100644 --- a/app/Http/Controllers/Admin/helpdesk/GroupController.php +++ b/app/Http/Controllers/Admin/helpdesk/GroupController.php @@ -139,9 +139,6 @@ class GroupController extends Controller //Updating can_assign_ticket field $assignTicket = $request->Input('can_assign_ticket'); $var->can_assign_ticket = $assignTicket; - //Updating can_trasfer_ticket field - $trasferTicket = $request->Input('can_trasfer_ticket'); - $var->can_trasfer_ticket = $trasferTicket; //Updating can_delete_ticket field $deleteTicket = $request->Input('can_delete_ticket'); $var->can_delete_ticket = $deleteTicket; diff --git a/app/Http/Controllers/Admin/helpdesk/SettingsController.php b/app/Http/Controllers/Admin/helpdesk/SettingsController.php index 33ccf9136..8402b6c4b 100644 --- a/app/Http/Controllers/Admin/helpdesk/SettingsController.php +++ b/app/Http/Controllers/Admin/helpdesk/SettingsController.php @@ -27,9 +27,11 @@ use App\Model\helpdesk\Utility\Date_time_format; use App\Model\helpdesk\Utility\Time_format; use App\Model\helpdesk\Utility\Timezones; // classes +use DB; use Exception; use Illuminate\Http\Request; use Input; +use Lang; /** * SettingsController. @@ -76,7 +78,7 @@ class SettingsController extends Controller /* Direct to Company Settings Page */ return view('themes.default1.admin.helpdesk.settings.company', compact('companys')); } catch (Exception $e) { - return redirect()->back()->with('fails', $e->errorInfo[2]); + return redirect()->back()->with('fails', $e->getMessage()); } } @@ -110,10 +112,31 @@ class SettingsController extends Controller return redirect('getcompany')->with('success', 'Company Updated Successfully'); } catch (Exception $e) { /* redirect to Index page with Fails Message */ - return redirect('getcompany')->with('fails', 'Company can not Updated'.'
  • '.$e->errorInfo[2].'
  • '); + return redirect('getcompany')->with('fails', 'Company can not Updated'.'
  • '.$e->getMessage().'
  • '); } } + /** + * function to delete system logo. + * + * @return type string + */ + public function deleteLogo() + { + $path = $_GET['data1']; //get file path of logo image + if (!unlink($path)) { + return 'false'; + } else { + $companys = Company::where('id', '=', 1)->first(); + $companys->logo = null; + $companys->use_logo = '0'; + $companys->save(); + + return 'true'; + } + // return $res; + } + /** * get the form for System setting page. * @@ -138,7 +161,7 @@ class SettingsController extends Controller /* Direct to System Settings Page */ return view('themes.default1.admin.helpdesk.settings.system', compact('systems', 'departments', 'timezones', 'time', 'date', 'date_time')); } catch (Exception $e) { - return redirect()->back()->with('fails', $e->errorInfo[2]); + return redirect()->back()->with('fails', $e->getMessage()); } } @@ -164,7 +187,7 @@ class SettingsController extends Controller return redirect('getsystem')->with('success', 'System Updated Successfully'); } catch (Exception $e) { /* redirect to Index page with Fails Message */ - return redirect('getsystem')->with('fails', 'System can not Updated'.'
  • '.$e->errorInfo[2].'
  • '); + return redirect('getsystem')->with('fails', 'System can not Updated'.'
  • '.$e->getMessage().'
  • '); } } @@ -190,7 +213,7 @@ class SettingsController extends Controller /* Direct to Ticket Settings Page */ return view('themes.default1.admin.helpdesk.settings.ticket', compact('tickets', 'slas', 'topics', 'priority')); } catch (Exception $e) { - return redirect()->back()->with('fails', $e->errorInfo[2]); + return redirect()->back()->with('fails', $e->getMessage()); } } @@ -225,7 +248,7 @@ class SettingsController extends Controller return redirect('getticket')->with('success', 'Ticket Updated Successfully'); } catch (Exception $e) { /* redirect to Index page with Fails Message */ - return redirect('getticket')->with('fails', 'Ticket can not Updated'.'
  • '.$e->errorInfo[2].'
  • '); + return redirect('getticket')->with('fails', 'Ticket can not Updated'.'
  • '.$e->getMessage().'
  • '); } } @@ -250,7 +273,7 @@ class SettingsController extends Controller /* Direct to Email Settings Page */ return view('themes.default1.admin.helpdesk.settings.email', compact('emails', 'templates', 'emails1')); } catch (Exception $e) { - return redirect()->back()->with('fails', $e->errorInfo[2]); + return redirect()->back()->with('fails', $e->getMessage()); } } @@ -271,8 +294,8 @@ class SettingsController extends Controller /* fill the values to email table */ $emails->fill($request->except('email_fetching', 'all_emails', 'email_collaborator', 'strip', 'attachment'))->save(); /* insert checkboxes to database */ - $emails->email_fetching = $request->input('email_fetching'); - $emails->notification_cron = $request->input('notification_cron'); + // $emails->email_fetching = $request->input('email_fetching'); + // $emails->notification_cron = $request->input('notification_cron'); $emails->all_emails = $request->input('all_emails'); $emails->email_collaborator = $request->input('email_collaborator'); $emails->strip = $request->input('strip'); @@ -283,7 +306,65 @@ class SettingsController extends Controller return redirect('getemail')->with('success', 'Email Updated Successfully'); } catch (Exception $e) { /* redirect to Index page with Fails Message */ - return redirect('getemail')->with('fails', 'Email can not Updated'.'
  • '.$e->errorInfo[2].'
  • '); + return redirect('getemail')->with('fails', 'Email can not Updated'.'
  • '.$e->getMessage().'
  • '); + } + } + + /** + * get the form for cron job setting page. + * + * @param type Email $email + * @param type Template $template + * @param type Emails $email1 + * + * @return type Response + */ + public function getSchedular(Email $email, Template $template, Emails $email1) + { + // try { + /* fetch the values of email from Email table */ + $emails = $email->whereId('1')->first(); + /* Fetch the values from Template table */ + $templates = $template->get(); + /* Fetch the values from Emails table */ + $emails1 = $email1->get(); + + return view('themes.default1.admin.helpdesk.settings.crone', compact('emails', 'templates', 'emails1')); + // } catch { + + // } + } + + /** + * Update the specified resource in storage for cron job. + * + * @param type Email $email + * @param type EmailRequest $request + * + * @return type Response + */ + public function postSchedular(Email $email, Template $template, Emails $email1, Request $request) + { + // dd($request); + try { + /* fetch the values of email request */ + $emails = $email->whereId('1')->first(); + if ($request->email_fetching) { + $emails->email_fetching = $request->email_fetching; + } else { + $emails->email_fetching = 0; + } + if ($request->notification_cron) { + $emails->notification_cron = $request->notification_cron; + } else { + $emails->notification_cron = 0; + } + $emails->save(); + /* redirect to Index page with Success Message */ + return redirect('job-scheduler')->with('success', Lang::get('lang.job-scheduler-success')); + } catch (Exception $e) { + /* redirect to Index page with Fails Message */ + return redirect('job-scheduler')->with('fails', Lang::get('lang.job-scheduler-error').'
  • '.$e->getMessage().'
  • '); } } @@ -353,7 +434,7 @@ class SettingsController extends Controller /* Direct to Responder Settings Page */ return view('themes.default1.admin.helpdesk.settings.responder', compact('responders')); } catch (Exception $e) { - return redirect()->back()->with('fails', $e->errorInfo[2]); + return redirect()->back()->with('fails', $e->getMessage()); } } @@ -383,7 +464,7 @@ class SettingsController extends Controller return redirect('getresponder')->with('success', 'Responder Updated Successfully'); } catch (Exception $e) { /* redirect to Index page with Fails Message */ - return redirect('getresponder')->with('fails', 'Responder can not Updated'.'
  • '.$e->errorInfo[2].'
  • '); + return redirect('getresponder')->with('fails', 'Responder can not Updated'.'
  • '.$e->getMessage().'
  • '); } } @@ -402,7 +483,7 @@ class SettingsController extends Controller /* Direct to Alert Settings Page */ return view('themes.default1.admin.helpdesk.settings.alert', compact('alerts')); } catch (Exception $e) { - return redirect()->back()->with('fails', $e->errorInfo[2]); + return redirect()->back()->with('fails', $e->getMessage()); } } @@ -471,7 +552,7 @@ class SettingsController extends Controller return redirect('getalert')->with('success', 'Alert Updated Successfully'); } catch (Exception $e) { /* redirect to Index page with Fails Message */ - return redirect('getalert')->with('fails', 'Alert can not Updated'.'
  • '.$e->errorInfo[2].'
  • '); + return redirect('getalert')->with('fails', 'Alert can not Updated'.'
  • '.$e->getMessage().'
  • '); } } diff --git a/app/Http/Controllers/Admin/helpdesk/TemplateController.php b/app/Http/Controllers/Admin/helpdesk/TemplateController.php index 050c1f76a..568dc84a0 100644 --- a/app/Http/Controllers/Admin/helpdesk/TemplateController.php +++ b/app/Http/Controllers/Admin/helpdesk/TemplateController.php @@ -324,7 +324,7 @@ class TemplateController extends Controller return redirect('getdiagno')->with('fails', 'Please provide E-mail address !'); } // sending mail via php mailer - $mail = $this->PhpMailController->sendmail($from = $this->PhpMailController->mailfrom('1', '0'), $to = ['email' => $email], $message = ['subject' => 'Checking the connection', 'scenario' => 'error-report', 'content' => 'Email Received Successfully'], $template_variables = ['system_error' => 'hello']); + $mail = $this->PhpMailController->sendmail($from = $this->PhpMailController->mailfrom('1', '0'), $to = ['email' => $email], $message = ['subject' => 'Checking the connection', 'scenario' => 'error-report', 'content' => 'Email Received Successfully'], $template_variables = ['system_error' => 'Email Received Successfully']); if ($mail == null) { return redirect('getdiagno')->with('fails', 'Please check your E-mail settings. Unable to send mails'); diff --git a/app/Http/Controllers/Admin/helpdesk/WorkflowController.php b/app/Http/Controllers/Admin/helpdesk/WorkflowController.php new file mode 100644 index 000000000..e83970caa --- /dev/null +++ b/app/Http/Controllers/Admin/helpdesk/WorkflowController.php @@ -0,0 +1,456 @@ + + */ +class WorkflowController extends Controller +{ + /** + * Create a new controller instance. + * constructor to check + * 1. authentication + * 2. user roles + * 3. roles must be agent. + * + * @return void + */ + public function __construct() + { + // checking authentication + $this->middleware('auth'); + // checking admin roles + $this->middleware('roles'); + } + + /** + * Display a listing of all the workflow. + * + * @return type + */ + public function index() + { + try { + return view('themes.default1.admin.helpdesk.manage.workflow.index'); + } catch (Exception $e) { + return view('404'); + } + } + + /** + * List of all the workflow in the system. + * + * @return type + */ + public function workFlowList() + { + // returns chumper datatable + return Datatable::collection(WorkflowName::All()) + /* searcable column name */ + ->searchColumns('name') + /* order column name and description */ + ->orderColumns('name') + /* add column name */ + ->addColumn('name', function ($model) { + return $model->name; + }) + /* add column status */ + ->addColumn('status', function ($model) { + if ($model->status == 1) { + return 'Active'; + } elseif ($model->status == 0) { + return 'Disabled'; + } + }) + /* add column order */ + ->addColumn('order', function ($model) { + return $model->order; + }) + /* add column rules */ + ->addColumn('rules', function ($model) { + $rules = WorkflowRules::where('workflow_id', '=', $model->id)->count(); + + return $rules; + }) + /* add column target */ + ->addColumn('target', function ($model) { + $target = $model->target; + $target1 = explode('-', $target); + if ($target1[0] == 'A') { + if ($target1[1] == 0) { + return 'Any'; + } elseif ($target1[1] == 1) { + return 'Web Forms'; + } elseif ($target1[1] == 2) { + return 'Email'; + } elseif ($target1[1] == 4) { + return 'API'; + } + } elseif ($target1[0] == 'E') { + $emails = Emails::where('id', '=', $target1[1])->first(); + + return $emails->email_address; + } + }) + /* add column created */ + ->addColumn('Created', function ($model) { + return TicketController::usertimezone($model->created_at); + }) + /* add column updated */ + ->addColumn('Updated', function ($model) { + return TicketController::usertimezone($model->updated_at); + }) + /* add column action */ + ->addColumn('Actions', function ($model) { + $confirmation = 'Are you sure?'; + + return "id)."'> Edit id)."'> Delete"; + }) + ->make(); + } + + /** + * Show the form for creating a new workflow. + * + * @return type Response + */ + public function create(Emails $emails) + { + // dd($emails); + foreach ($emails->lists('email_address', 'id') as $key => $email) { + $email_data["E-$key"] = $email; + } +// dd($email_data); +// dd($emails->lists('email_address' , 'id')); + $emails = $email_data; + try { + // $emails = $emails->get(); + return view('themes.default1.admin.helpdesk.manage.workflow.create', compact('emails')); + } catch (Exception $e) { + return view('404'); + } + } + + /** + * Store a new workflow in to the system. + * + * @param \App\Http\Requests\helpdesk\WorkflowCreateRequest $request + * + * @return type view + */ + public function store(WorkflowCreateRequest $request) + { + //dd($request); + try { + // store a new workflow credentials in to the system + $workflow_name = new WorkflowName(); + $workflow_name->name = $request->name; + $workflow_name->status = $request->status; + $workflow_name->order = $request->execution_order; + $workflow_name->target = $request->target_channel; + $workflow_name->internal_note = $request->internal_note; + $workflow_name->save(); + + $rules = $request->rule; + $actions = $request->action; + // store workflow rules into the system + foreach ($rules as $rule) { + $workflow_rule = new WorkflowRules(); + $workflow_rule->workflow_id = $workflow_name->id; + $workflow_rule->matching_scenario = $rule['a']; + $workflow_rule->matching_relation = $rule['b']; + $workflow_rule->matching_value = $rule['c']; + $workflow_rule->save(); + } + // store a new workflow action into the system + foreach ($actions as $action) { + $workflow_action = new WorkflowAction(); + $workflow_action->workflow_id = $workflow_name->id; + $workflow_action->condition = $action['a']; + $workflow_action->action = $action['b']; + $workflow_action->save(); + } + + return redirect('workflow')->with('success', 'Workflow Created Successfully'); + } catch (Exception $e) { + return redirect()->back()->with('fails', $e->getMessage()); + } + } + + /** + * Editing the details of the banned users. + * + * @param type $id + * @param User $ban + * + * @return type Response + */ + public function edit($id, WorkflowName $work_flow_name, Emails $emails, WorkflowRules $workflow_rule, WorkflowAction $workflow_action) + { + try { + $emails = $emails->get(); + $workflow = $work_flow_name->whereId($id)->first(); + $workflow_rules = $workflow_rule->whereWorkflow_id($id)->get(); + $workflow_actions = $workflow_action->whereWorkflow_id($id)->get(); + + return view('themes.default1.admin.helpdesk.manage.workflow.edit', compact('id', 'workflow', 'emails', 'workflow_rules', 'workflow_actions')); + } catch (Exception $e) { + return view('404'); + } + } + + /** + * Update ticket workflow. + * + * @param type $id + * @param \App\Http\Requests\helpdesk\WorkflowUpdateRequest $request + * + * @return type view + */ + public function update($id, WorkflowUpdateRequest $request) + { + try { + // store a new workflow credentials in to the system + $workflow_name = WorkflowName::whereId($id)->first(); + $workflow_name->name = $request->name; + $workflow_name->status = $request->status; + $workflow_name->order = $request->execution_order; + $workflow_name->target = $request->target_channel; + $workflow_name->internal_note = $request->internal_note; + $workflow_name->save(); + + $rules = $request->rule; + $actions = $request->action; + // removing old foreign values to insert an updated one + WorkflowAction::where('workflow_id', '=', $id)->delete(); + WorkflowRules::where('workflow_id', '=', $id)->delete(); + // update workflow rules into the system + foreach ($rules as $rule) { + $workflow_rule = new WorkflowRules(); + $workflow_rule->workflow_id = $workflow_name->id; + $workflow_rule->matching_scenario = $rule['a']; + $workflow_rule->matching_relation = $rule['b']; + $workflow_rule->matching_value = $rule['c']; + $workflow_rule->save(); + } + // update workflow action into the system + foreach ($actions as $action) { + $workflow_action = new WorkflowAction(); + $workflow_action->workflow_id = $workflow_name->id; + $workflow_action->condition = $action['a']; + $workflow_action->action = $action['b']; + $workflow_action->save(); + } + + return redirect('workflow')->with('success', 'Workflow Updated Successfully'); + } catch (Exception $e) { + return redirect()->back()->with('fails', $e->getMessage()); + } + } + + /** + * function to delete workflow. + * + * @param type $id + */ + public function destroy($id) + { + try { + // remove all the contents of workflow + $workflow_action = WorkflowAction::where('workflow_id', '=', $id)->delete(); + $workflow_rules = WorkflowRules::where('workflow_id', '=', $id)->delete(); + $workflow = WorkflowName::whereId($id)->delete(); + + return redirect('workflow')->with('success', 'Workflow Deleted Successfully'); + } catch (Exception $e) { + return redirect()->back()->with('fails', $e->getMessage()); + } + } + + /** + * function to select action. + * + * @param type $id + * @param \Illuminate\Http\Request $request + * + * @return type void + */ + public function selectAction($id, Request $request) + { + if ($request->option == 'reject') { + return $this->rejectTicket($id); + } elseif ($request->option == 'department') { + return $this->department($id); + } elseif ($request->option == 'priority') { + return $this->priority($id); + } elseif ($request->option == 'sla') { + return $this->slaPlan($id); + } elseif ($request->option == 'team') { + return $this->assignTeam($id); + } elseif ($request->option == 'agent') { + return $this->assignAgent($id); + } elseif ($request->option == 'helptopic') { + return $this->helptopic($id); + } elseif ($request->option == 'status') { + return $this->ticketStatus($id); + } + } + + /** + * function to reject ticket. + * + * @return string + */ + public function rejectTicket($id) + { + $var = 'Reject '; + + return $var; + } + + /** + * function to return deprtment select option. + * + * @return type string + */ + public function department($id) + { + $departments = Department::all(); + $var = "'; + + return $var; + } + + /** + * function to return the priority select option. + * + * @return type string + */ + public function priority($id) + { + $priorities = Ticket_Priority::all(); + $var = "'; + + return $var; + } + + /** + * function to return the slaplan select option. + * + * @return type string + */ + public function slaPlan($id) + { + $sla_plans = Sla_plan::where('status', '=', 1)->get(); + $var = "'; + + return $var; + } + + /** + * function to get system team select option. + * + * @return type string + */ + public function assignTeam($id) + { + $teams = Teams::where('status', '=', 1)->get(); + $var = "'; + + return $var; + } + + /** + * function to get system agents select option. + * + * @return type string + */ + public function assignAgent($id) + { + $users = User::where('role', '!=', 'user')->where('active', '=', 1)->get(); + $var = "'; + + return $var; + } + + /** + * function to get the helptopic select option. + * + * @return type string + */ + public function helptopic($id) + { + $help_topics = Help_topic::where('status', '=', 1)->get(); + $var = "'; + + return $var; + } + + /** + * function to get the select option to choose the ticket status. + * + * @return type string + */ + public function ticketStatus($id) + { + $ticket_status = Ticket_Status::all(); + $var = "'; + + return $var; + } +} diff --git a/app/Http/Controllers/Agent/helpdesk/MailController.php b/app/Http/Controllers/Agent/helpdesk/MailController.php index 56901b690..76c6f1ced 100644 --- a/app/Http/Controllers/Agent/helpdesk/MailController.php +++ b/app/Http/Controllers/Agent/helpdesk/MailController.php @@ -35,9 +35,9 @@ class MailController extends Controller * * @param type TicketController $TicketController */ - public function __construct(TicketController $TicketController) + public function __construct(TicketWorkflowController $TicketWorkflowController) { - $this->TicketController = $TicketController; + $this->TicketWorkflowController = $TicketWorkflowController; } /** @@ -76,6 +76,9 @@ class MailController extends Controller $protocol_value = $e_mail->mailbox_protocol; $get_mailboxprotocol = MailboxProtocol::where('id', '=', $protocol_value)->first(); $protocol = $get_mailboxprotocol->value; + } elseif ($e_mail->fetching_encryption == '/none') { + $fetching_encryption2 = '/novalidate-cert'; + $protocol = $fetching_encryption2; } else { if ($e_mail->fetching_protocol) { $fetching_protocol = '/'.$e_mail->fetching_protocol; @@ -83,7 +86,7 @@ class MailController extends Controller $fetching_protocol = ''; } if ($e_mail->fetching_encryption) { - $fetching_encryption = '/'.$e_mail->fetching_encryption; + $fetching_encryption = $e_mail->fetching_encryption; } else { $fetching_encryption = ''; } @@ -130,7 +133,9 @@ class MailController extends Controller $assign = $get_helptopic->auto_assign; $form_data = null; - $result = $this->TicketController->create_user($fromaddress, $fromname, $subject, $body, $phone, $helptopic, $sla, $priority, $source, $collaborator, $dept, $assign, $form_data, $auto_response); + $team_assign = null; + $ticket_status = null; + $result = $this->TicketWorkflowController->workflow($fromaddress, $fromname, $subject, $body, $phone, $helptopic, $sla, $priority, $source, $collaborator, $dept, $assign, $team_assign, $ticket_status, $form_data, $auto_response); // dd($result); if ($result[1] == true) { $ticket_table = Tickets::where('ticket_number', '=', $result[0])->first(); diff --git a/app/Http/Controllers/Agent/helpdesk/NotificationController.php b/app/Http/Controllers/Agent/helpdesk/NotificationController.php index 41c6c6b6b..3b6a4969b 100644 --- a/app/Http/Controllers/Agent/helpdesk/NotificationController.php +++ b/app/Http/Controllers/Agent/helpdesk/NotificationController.php @@ -76,6 +76,10 @@ class NotificationController extends Controller $view = View::make('emails.notifications.admin', ['company' => $company, 'name' => $user_name]); $contents = $view->render(); $this->PhpMailController->sendEmail($from = $this->PhpMailController->mailfrom('1', '0'), $to = ['name' => $user_name, 'email' => $email], $message = ['subject' => 'Daily Report', 'scenario' => null, 'body' => $contents]); + +// \Mail::send('emails.notifications.admin', ['company' => $company, 'name' => $user_name], function ($message) use ($email, $user_name, $company) { +// $message->to($email, $user_name)->subject($company.' Daily Report '); +// }); } } @@ -99,6 +103,10 @@ class NotificationController extends Controller $view = View::make('emails.notifications.manager', ['company' => $company, 'name' => $user_name]); $contents = $view->render(); $this->PhpMailController->sendEmail($from = $this->PhpMailController->mailfrom('1', '0'), $to = ['name' => $user_name, 'email' => $email], $message = ['subject' => 'Daily Report', 'scenario' => null, 'body' => $contents]); + +// \Mail::send('emails.notifications.manager', ['company' => $company, 'name' => $user_name, 'dept_id' => $dept->id, 'dept_name' => $dept->name], function ($message) use ($email, $user_name, $company, $dept_name) { +// $message->to($email, $user_name)->subject($company.' Daily Report for department manager of '.$dept_name.' department.'); +// }); } } } @@ -124,6 +132,10 @@ class NotificationController extends Controller $view = View::make('emails.notifications.lead', ['company' => $company, 'name' => $user_name]); $contents = $view->render(); $this->PhpMailController->sendEmail($from = $this->PhpMailController->mailfrom('1', '0'), $to = ['name' => $user_name, 'email' => $email], $message = ['subject' => 'Daily Report', 'scenario' => null, 'body' => $contents]); + +// \Mail::send('emails.notifications.lead', ['company' => $company, 'name' => $user_name, 'team_id' => $team->id], function ($message) use ($email, $user_name, $company, $team_name) { +// $message->to($email, $user_name)->subject($company.' Daily Report for Team Lead of team '.$team_name); +// }); } } } @@ -145,6 +157,10 @@ class NotificationController extends Controller $view = View::make('emails.notifications.agent', ['company' => $company, 'name' => $user_name, 'user_id' => $user->id]); $contents = $view->render(); $this->PhpMailController->sendEmail($from = $this->PhpMailController->mailfrom('1', '0'), $to = ['name' => $user_name, 'email' => $email], $message = ['subject' => 'Daily Report', 'scenario' => null, 'body' => $contents]); + +// \Mail::send('emails.notifications.agent', ['company' => $company, 'name' => $user_name, 'user_id' => 1], function ($message) use ($email, $user_name, $company) { +// $message->to($email, $user_name)->subject($company.' Daily Report for Agents'); +// }); } } @@ -166,4 +182,13 @@ class NotificationController extends Controller return $company; } + + // // testing + // public function test(){ + // $email = "sujit.prasad@ladybirdweb.com"; + // $user_name = "sujit prasad"; + // \Mail::send('emails.notifications.test', ['user_id' => 1], function ($message) use($email, $user_name) { + // $message->to($email, $user_name)->subject('testing reporting'); + // }); + // } } diff --git a/app/Http/Controllers/Agent/helpdesk/Ticket2Controller.php b/app/Http/Controllers/Agent/helpdesk/Ticket2Controller.php index d2db4a300..dccd27ac5 100644 --- a/app/Http/Controllers/Agent/helpdesk/Ticket2Controller.php +++ b/app/Http/Controllers/Agent/helpdesk/Ticket2Controller.php @@ -8,18 +8,11 @@ use App\Http\Controllers\Controller; // requests // models use App\Model\helpdesk\Agent\Department; -use App\Model\helpdesk\Ticket\Ticket_attachments; -use App\Model\helpdesk\Ticket\Ticket_Collaborator; -use App\Model\helpdesk\Ticket\Ticket_Priority; -use App\Model\helpdesk\Ticket\Ticket_Thread; use App\Model\helpdesk\Ticket\Tickets; use App\User; use Auth; -use DB; // classes -use Illuminate\support\Collection; -use Input; -use UTC; +use Ttable; /** * TicketController2. @@ -67,89 +60,7 @@ class Ticket2Controller extends Controller $tickets = Tickets::where('status', '=', 1)->where('isanswered', '=', 0)->where('dept_id', '=', $dept->id)->get(); } - return \Datatable::collection(new Collection($tickets)) - ->addColumn('id', function ($ticket) { - return ""; - }) - ->addColumn('subject', function ($ticket) { - $subject = DB::table('ticket_thread')->select('title')->where('ticket_id', '=', $ticket->id)->first(); - if (isset($subject->title)) { - $string = $subject->title; - if (strlen($string) > 20) { - $stringCut = substr($string, 0, 30); - $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; - } - } else { - $string = '(no subject)'; - } - //collabrations - $collaborators = DB::table('ticket_collaborator')->where('ticket_id', '=', $ticket->id)->get(); - $collab = count($collaborators); - if ($collab > 0) { - $collabString = ' '; - } else { - $collabString = null; - } - $threads = Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); // - $count = Ticket_Thread::where('ticket_id', '=', $ticket->id)->count(); // - $attachment = Ticket_attachments::where('thread_id', '=', $threads->id)->get(); - $attachCount = count($attachment); - if ($attachCount > 0) { - $attachString = ' '; - } else { - $attachString = ''; - } - - return "id])."' title='".$subject->title."'>".$string." (".$count.")".$collabString.$attachString; - }) - ->addColumn('ticket_number', function ($ticket) { - return "id])."' title='".$ticket->ticket_number."'>#".$ticket->ticket_number.''; - }) - ->addColumn('priority', function ($ticket) { - $priority = DB::table('ticket_priority')->select('priority_desc', 'priority_color')->where('priority_id', '=', $ticket->priority_id)->first(); - - return ''.$priority->priority_desc.''; - }) - ->addColumn('from', function ($ticket) { - $from = DB::table('users')->select('user_name')->where('id', '=', $ticket->user_id)->first(); - - return "".$from->user_name.''; - }) - ->addColumn('Last Replier', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->where('is_internal', '=', 0)->max('id'); - $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); - $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); - if ($LastResponse->role == 'user') { - $rep = '#F39C12'; - $username = $LastResponse->user_name; - } else { - $rep = '#000'; - $username = $LastResponse->first_name.' '.$LastResponse->last_name; - if ($LastResponse->first_name == null || $LastResponse->last_name == null) { - $username = $LastResponse->user_name; - } - } - - return "".$username.''; - }) - ->addColumn('assigned_to', function ($ticket) { - if ($ticket->assigned_to == null) { - return "Unassigned"; - } else { - $assign = DB::table('users')->where('id', '=', $ticket->assigned_to)->first(); - - return "".$assign->first_name.' '.$assign->last_name.''; - } - }) - ->addColumn('Last', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = Ticket_Thread::select('updated_at')->where('id', '=', $TicketData)->first(); - - return UTC::usertimezone($TicketDatarow->updated_at); - }) - ->searchColumns('subject', 'from', 'assigned_to', 'ticket_number', 'priority') - ->orderColumns('subject', 'from', 'assigned_to', 'Last Replier', 'ticket_number', 'priority', 'Last') - ->make(); + return Ttable::getTable($tickets); } /** @@ -180,89 +91,7 @@ class Ticket2Controller extends Controller $tickets = Tickets::where('status', '=', '2')->where('dept_id', '=', $dept->id)->get(); } - return \Datatable::collection(new Collection($tickets)) - ->addColumn('id', function ($ticket) { - return ""; - }) - ->addColumn('subject', function ($ticket) { - $subject = DB::table('ticket_thread')->select('title')->where('ticket_id', '=', $ticket->id)->first(); - if (isset($subject->title)) { - $string = $subject->title; - if (strlen($string) > 20) { - $stringCut = substr($string, 0, 30); - $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; - } - } else { - $string = '(no subject)'; - } - //collabrations - $collaborators = DB::table('ticket_collaborator')->where('ticket_id', '=', $ticket->id)->get(); - $collab = count($collaborators); - if ($collab > 0) { - $collabString = ' '; - } else { - $collabString = null; - } - $threads = Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); - $count = Ticket_Thread::where('ticket_id', '=', $ticket->id)->count(); - $attachment = Ticket_attachments::where('thread_id', '=', $threads->id)->get(); - $attachCount = count($attachment); - if ($attachCount > 0) { - $attachString = ' '; - } else { - $attachString = ''; - } - - return "id])."' title='".$subject->title."'>".$string." (".$count.")".$collabString.$attachString; - }) - ->addColumn('ticket_number', function ($ticket) { - return "id])."' title='".$ticket->ticket_number."'>#".$ticket->ticket_number.''; - }) - ->addColumn('priority', function ($ticket) { - $priority = DB::table('ticket_priority')->select('priority_desc', 'priority_color')->where('priority_id', '=', $ticket->priority_id)->first(); - - return ''.$priority->priority_desc.''; - }) - ->addColumn('from', function ($ticket) { - $from = DB::table('users')->select('user_name')->where('id', '=', $ticket->user_id)->first(); - - return "".$from->user_name.''; - }) - ->addColumn('Last Replier', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->where('is_internal', '!=', 1)->max('id'); - $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); - $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); - if ($LastResponse->role == 'user') { - $rep = '#F39C12'; - $username = $LastResponse->user_name; - } else { - $rep = '#000'; - $username = $LastResponse->first_name.' '.$LastResponse->last_name; - if ($LastResponse->first_name == null || $LastResponse->last_name == null) { - $username = $LastResponse->user_name; - } - } - - return "".$username.''; - }) - ->addColumn('assigned_to', function ($ticket) { - if ($ticket->assigned_to == null) { - return "Usernassigned"; - } else { - $assign = DB::table('users')->where('id', '=', $ticket->assigned_to)->first(); - - return "".$assign->first_name.' '.$assign->last_name.''; - } - }) - ->addColumn('Last', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = Ticket_Thread::select('updated_at')->where('id', '=', $TicketData)->first(); - - return UTC::usertimezone($TicketDatarow->updated_at); - }) - ->searchColumns('subject', 'from', 'assigned_to', 'ticket_number', 'priority') - ->orderColumns('subject', 'from', 'assigned_to', 'Last Replier', 'ticket_number', 'priority', 'Last') - ->make(); + return Ttable::getTable($tickets); } /** @@ -298,88 +127,6 @@ class Ticket2Controller extends Controller $tickets = Tickets::where('status', '=', '1')->where('assigned_to', '>', 0)->where('dept_id', '=', $dept->id)->get(); } - return \Datatable::collection(new Collection($tickets)) - ->addColumn('id', function ($ticket) { - return ""; - }) - ->addColumn('subject', function ($ticket) { - $subject = DB::table('ticket_thread')->select('title')->where('ticket_id', '=', $ticket->id)->first(); - if (isset($subject->title)) { - $string = $subject->title; - if (strlen($string) > 20) { - $stringCut = substr($string, 0, 30); - $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; - } - } else { - $string = '(no subject)'; - } - //collabrations - $collaborators = DB::table('ticket_collaborator')->where('ticket_id', '=', $ticket->id)->get(); - $collab = count($collaborators); - if ($collab > 0) { - $collabString = ' '; - } else { - $collabString = null; - } - $threads = Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); - $count = Ticket_Thread::where('ticket_id', '=', $ticket->id)->count(); - $attachment = Ticket_attachments::where('thread_id', '=', $threads->id)->get(); - $attachCount = count($attachment); - if ($attachCount > 0) { - $attachString = ' '; - } else { - $attachString = ''; - } - - return "id])."' title='".$subject->title."'>".$string." (".$count.")".$collabString.$attachString; - }) - ->addColumn('ticket_number', function ($ticket) { - return "id])."' title='".$ticket->ticket_number."'>#".$ticket->ticket_number.''; - }) - ->addColumn('priority', function ($ticket) { - $priority = DB::table('ticket_priority')->select('priority_desc', 'priority_color')->where('priority_id', '=', $ticket->priority_id)->first(); - - return ''.$priority->priority_desc.''; - }) - ->addColumn('from', function ($ticket) { - $from = DB::table('users')->select('user_name')->where('id', '=', $ticket->user_id)->first(); - - return "".$from->user_name.''; - }) - ->addColumn('Last Replier', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->where('is_internal', '!=', 1)->max('id'); - $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); - $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); - if ($LastResponse->role == 'user') { - $rep = '#F39C12'; - $username = $LastResponse->user_name; - } else { - $rep = '#000'; - $username = $LastResponse->first_name.' '.$LastResponse->last_name; - if ($LastResponse->first_name == null || $LastResponse->last_name == null) { - $username = $LastResponse->user_name; - } - } - - return "".$username.''; - }) - ->addColumn('assigned_to', function ($ticket) { - if ($ticket->assigned_to == null) { - return "Usernassigned"; - } else { - $assign = DB::table('users')->where('id', '=', $ticket->assigned_to)->first(); - - return "".$assign->first_name.' '.$assign->last_name.''; - } - }) - ->addColumn('Last', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = Ticket_Thread::select('updated_at')->where('id', '=', $TicketData)->first(); - - return UTC::usertimezone($TicketDatarow->updated_at); - }) - ->searchColumns('subject', 'from', 'assigned_to', 'ticket_number', 'priority') - ->orderColumns('subject', 'from', 'assigned_to', 'Last Replier', 'ticket_number', 'priority', 'Last') - ->make(); + return Ttable::getTable($tickets); } } diff --git a/app/Http/Controllers/Agent/helpdesk/TicketController.php b/app/Http/Controllers/Agent/helpdesk/TicketController.php index 41a13100b..dbf955604 100644 --- a/app/Http/Controllers/Agent/helpdesk/TicketController.php +++ b/app/Http/Controllers/Agent/helpdesk/TicketController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Agent\helpdesk; // controllers +use App\Http\Controllers\Common\NotificationController; use App\Http\Controllers\Common\PhpMailController; use App\Http\Controllers\Controller; // requests @@ -54,9 +55,10 @@ class TicketController extends Controller * * @return type response */ - public function __construct(PhpMailController $PhpMailController) + public function __construct(PhpMailController $PhpMailController, NotificationController $NotificationController) { $this->PhpMailController = $PhpMailController; + $this->NotificationController = $NotificationController; $this->middleware('auth'); } @@ -79,91 +81,7 @@ class TicketController extends Controller $tickets = Tickets::where('status', 1)->where('dept_id', '=', $dept->id)->get(); } - return \Datatable::collection(new Collection($tickets)) - ->addColumn('id', function ($ticket) { - return ""; - }) - ->addColumn('subject', function ($ticket) { - $subject = DB::table('ticket_thread')->select('title')->where('ticket_id', '=', $ticket->id)->first(); - if (isset($subject->title)) { - $string = $subject->title; - if (strlen($string) > 20) { - $stringCut = substr($string, 0, 30); - $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; - } - } else { - $string = '(no subject)'; - } - //collabrations - $collaborators = DB::table('ticket_collaborator')->where('ticket_id', '=', $ticket->id)->get(); - $collab = count($collaborators); - if ($collab > 0) { - $collabString = ' '; - } else { - $collabString = null; - } - - $threads = Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); // - $count = Ticket_Thread::where('ticket_id', '=', $ticket->id)->count(); //Ticket_Thread::where('ticket_id', '=', $ticket->id)->get(); - - $attachment = Ticket_attachments::where('thread_id', '=', $threads->id)->get(); - $attachCount = count($attachment); - if ($attachCount > 0) { - $attachString = ' '; - } else { - $attachString = ''; - } - - return "id])."' title='".$subject->title."'>".$string." (".$count.")".$collabString.$attachString; - }) - ->addColumn('ticket_number', function ($ticket) { - return "id])."' title='".$ticket->ticket_number."'>#".$ticket->ticket_number.''; - }) - ->addColumn('priority', function ($ticket) { - $priority = DB::table('ticket_priority')->select('priority_desc', 'priority_color')->where('priority_id', '=', $ticket->priority_id)->first(); - - return ''.$priority->priority_desc.''; - }) - ->addColumn('from', function ($ticket) { - $from = DB::table('users')->select('user_name')->where('id', '=', $ticket->user_id)->first(); - - return "".$from->user_name.''; - }) - ->addColumn('Last Replier', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); - $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); - if ($LastResponse->role == 'user') { - $rep = '#F39C12'; - $username = $LastResponse->user_name; - } else { - $rep = '#000'; - $username = $LastResponse->first_name.' '.$LastResponse->last_name; - if ($LastResponse->first_name == null || $LastResponse->last_name == null) { - $username = $LastResponse->user_name; - } - } - - return "".$username.''; - }) - ->addColumn('assigned_to', function ($ticket) { - if ($ticket->assigned_to == null) { - return "Unassigned"; - } else { - $assign = DB::table('users')->where('id', '=', $ticket->assigned_to)->first(); - - return "".$assign->first_name.' '.$assign->last_name.''; - } - }) - ->addColumn('Last', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = Ticket_Thread::select('updated_at')->where('id', '=', $TicketData)->first(); - - return UTC::usertimezone($TicketDatarow->updated_at); - }) - ->searchColumns('subject', 'from', 'assigned_to', 'ticket_number', 'priority') - ->orderColumns('subject', 'from', 'assigned_to', 'Last Replier', 'ticket_number', 'priority', 'Last') - ->make(); + return $this->getTable($tickets); } /** @@ -185,89 +103,7 @@ class TicketController extends Controller $tickets = Tickets::where('status', '=', 1)->where('isanswered', '=', 0)->where('dept_id', '=', $dept->id)->get(); } - return \Datatable::collection(new Collection($tickets)) - ->addColumn('id', function ($ticket) { - return ""; - }) - ->addColumn('subject', function ($ticket) { - $subject = DB::table('ticket_thread')->select('title')->where('ticket_id', '=', $ticket->id)->first(); - if (isset($subject->title)) { - $string = $subject->title; - if (strlen($string) > 20) { - $stringCut = substr($string, 0, 30); - $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; - } - } else { - $string = '(no subject)'; - } - //collabrations - $collaborators = DB::table('ticket_collaborator')->where('ticket_id', '=', $ticket->id)->get(); - $collab = count($collaborators); - if ($collab > 0) { - $collabString = ' '; - } else { - $collabString = null; - } - $threads = Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); // - $count = Ticket_Thread::where('ticket_id', '=', $ticket->id)->count(); // - $attachment = Ticket_attachments::where('thread_id', '=', $threads->id)->get(); - $attachCount = count($attachment); - if ($attachCount > 0) { - $attachString = ' '; - } else { - $attachString = ''; - } - - return "id])."' title='".$subject->title."'>".$string." (".$count.")".$collabString.$attachString; - }) - ->addColumn('ticket_number', function ($ticket) { - return "id])."' title='".$ticket->ticket_number."'>#".$ticket->ticket_number.''; - }) - ->addColumn('priority', function ($ticket) { - $priority = DB::table('ticket_priority')->select('priority_desc', 'priority_color')->where('priority_id', '=', $ticket->priority_id)->first(); - - return ''.$priority->priority_desc.''; - }) - ->addColumn('from', function ($ticket) { - $from = DB::table('users')->select('user_name')->where('id', '=', $ticket->user_id)->first(); - - return "".$from->user_name.''; - }) - ->addColumn('Last Replier', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->where('is_internal', '=', 0)->max('id'); - $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); - $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); - if ($LastResponse->role == 'user') { - $rep = '#F39C12'; - $username = $LastResponse->user_name; - } else { - $rep = '#000'; - $username = $LastResponse->first_name.' '.$LastResponse->last_name; - if ($LastResponse->first_name == null || $LastResponse->last_name == null) { - $username = $LastResponse->user_name; - } - } - - return "".$username.''; - }) - ->addColumn('assigned_to', function ($ticket) { - if ($ticket->assigned_to == null) { - return "Unassigned"; - } else { - $assign = DB::table('users')->where('id', '=', $ticket->assigned_to)->first(); - - return "".$assign->first_name.' '.$assign->last_name.''; - } - }) - ->addColumn('Last', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = Ticket_Thread::select('updated_at')->where('id', '=', $TicketData)->first(); - - return UTC::usertimezone($TicketDatarow->updated_at); - }) - ->searchColumns('subject', 'from', 'assigned_to', 'ticket_number', 'priority') - ->orderColumns('subject', 'from', 'assigned_to', 'Last Replier', 'ticket_number', 'priority', 'Last') - ->make(); + return $this->getTable($tickets); } /** @@ -289,89 +125,7 @@ class TicketController extends Controller $tickets = Tickets::where('status', '=', 1)->where('isanswered', '=', 1)->where('dept_id', '=', $dept->id)->get(); } - return \Datatable::collection(new Collection($tickets)) - ->addColumn('id', function ($ticket) { - return ""; - }) - ->addColumn('subject', function ($ticket) { - $subject = DB::table('ticket_thread')->select('title')->where('ticket_id', '=', $ticket->id)->first(); - if (isset($subject->title)) { - $string = $subject->title; - if (strlen($string) > 20) { - $stringCut = substr($string, 0, 30); - $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; - } - } else { - $string = '(no subject)'; - } - //collabrations - $collaborators = DB::table('ticket_collaborator')->where('ticket_id', '=', $ticket->id)->get(); - $collab = count($collaborators); - if ($collab > 0) { - $collabString = ' '; - } else { - $collabString = null; - } - $threads = Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); - $count = Ticket_Thread::where('ticket_id', '=', $ticket->id)->count(); - $attachment = Ticket_attachments::where('thread_id', '=', $threads->id)->get(); - $attachCount = count($attachment); - if ($attachCount > 0) { - $attachString = ' '; - } else { - $attachString = ''; - } - - return "id])."' title='".$subject->title."'>".$string." (".$count.")".$collabString.$attachString; - }) - ->addColumn('ticket_number', function ($ticket) { - return "id])."' title='".$ticket->ticket_number."'>#".$ticket->ticket_number.''; - }) - ->addColumn('priority', function ($ticket) { - $priority = DB::table('ticket_priority')->select('priority_desc', 'priority_color')->where('priority_id', '=', $ticket->priority_id)->first(); - - return ''.$priority->priority_desc.''; - }) - ->addColumn('from', function ($ticket) { - $from = DB::table('users')->select('user_name')->where('id', '=', $ticket->user_id)->first(); - - return "".$from->user_name.''; - }) - ->addColumn('Last Replier', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->where('is_internal', '!=', 1)->max('id'); - $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); - $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); - if ($LastResponse->role == 'user') { - $rep = '#F39C12'; - $username = $LastResponse->user_name; - } else { - $rep = '#000'; - $username = $LastResponse->first_name.' '.$LastResponse->last_name; - if ($LastResponse->first_name == null || $LastResponse->last_name == null) { - $username = $LastResponse->user_name; - } - } - - return "".$username.''; - }) - ->addColumn('assigned_to', function ($ticket) { - if ($ticket->assigned_to == null) { - return "Usernassigned"; - } else { - $assign = DB::table('users')->where('id', '=', $ticket->assigned_to)->first(); - - return "".$assign->first_name.' '.$assign->last_name.''; - } - }) - ->addColumn('Last', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = Ticket_Thread::select('updated_at')->where('id', '=', $TicketData)->first(); - - return UTC::usertimezone($TicketDatarow->updated_at); - }) - ->searchColumns('subject', 'from', 'assigned_to', 'ticket_number', 'priority') - ->orderColumns('subject', 'from', 'assigned_to', 'Last Replier', 'ticket_number', 'priority', 'Last') - ->make(); + return $this->getTable($tickets); } /** @@ -393,89 +147,7 @@ class TicketController extends Controller $tickets = Tickets::where('status', '=', 1)->where('assigned_to', '=', Auth::user()->id)->get(); } - return \Datatable::collection(new Collection($tickets)) - ->addColumn('id', function ($ticket) { - return ""; - }) - ->addColumn('subject', function ($ticket) { - $subject = DB::table('ticket_thread')->select('title')->where('ticket_id', '=', $ticket->id)->first(); - if (isset($subject->title)) { - $string = $subject->title; - if (strlen($string) > 20) { - $stringCut = substr($string, 0, 30); - $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; - } - } else { - $string = '(no subject)'; - } - //collabrations - $collaborators = DB::table('ticket_collaborator')->where('ticket_id', '=', $ticket->id)->get(); - $collab = count($collaborators); - if ($collab > 0) { - $collabString = ' '; - } else { - $collabString = null; - } - $threads = Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); - $count = Ticket_Thread::where('ticket_id', '=', $ticket->id)->count(); - $attachment = Ticket_attachments::where('thread_id', '=', $threads->id)->get(); - $attachCount = count($attachment); - if ($attachCount > 0) { - $attachString = ' '; - } else { - $attachString = ''; - } - - return "id])."' title='".$subject->title."'>".$string." (".$count.")".$collabString.$attachString; - }) - ->addColumn('ticket_number', function ($ticket) { - return "id])."' title='".$ticket->ticket_number."'>#".$ticket->ticket_number.''; - }) - ->addColumn('priority', function ($ticket) { - $priority = DB::table('ticket_priority')->select('priority_desc', 'priority_color')->where('priority_id', '=', $ticket->priority_id)->first(); - - return ''.$priority->priority_desc.''; - }) - ->addColumn('from', function ($ticket) { - $from = DB::table('users')->select('user_name')->where('id', '=', $ticket->user_id)->first(); - - return "".$from->user_name.''; - }) - ->addColumn('Last Replier', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->where('is_internal', '!=', 1)->max('id'); - $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); - $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); - if ($LastResponse->role == 'user') { - $rep = '#F39C12'; - $username = $LastResponse->user_name; - } else { - $rep = '#000'; - $username = $LastResponse->first_name.' '.$LastResponse->last_name; - if ($LastResponse->first_name == null || $LastResponse->last_name == null) { - $username = $LastResponse->user_name; - } - } - - return "".$username.''; - }) - ->addColumn('assigned_to', function ($ticket) { - if ($ticket->assigned_to == null) { - return "Usernassigned"; - } else { - $assign = DB::table('users')->where('id', '=', $ticket->assigned_to)->first(); - - return "".$assign->first_name.' '.$assign->last_name.''; - } - }) - ->addColumn('Last', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = Ticket_Thread::select('updated_at')->where('id', '=', $TicketData)->first(); - - return UTC::usertimezone($TicketDatarow->updated_at); - }) - ->searchColumns('subject', 'from', 'assigned_to', 'ticket_number', 'priority') - ->orderColumns('subject', 'from', 'assigned_to', 'Last Replier', 'ticket_number', 'priority', 'Last') - ->make(); + return $this->getTable($tickets); } /** @@ -488,6 +160,39 @@ class TicketController extends Controller return view('themes.default1.agent.helpdesk.ticket.overdue'); } + public function getOverdueTickets() + { + if (Auth::user()->role == 'agent') { + $dept = Department::where('id', '=', Auth::user()->primary_dpt)->first(); + $overdues = Tickets::where('status', '=', 1)->where('isanswered', '=', 0)->where('dept_id', '=', $dept->id)->orderBy('id', 'DESC')->get(); + } else { + $overdues = Tickets::where('status', '=', 1)->where('isanswered', '=', 0)->orderBy('id', 'DESC')->get(); + } + if (count($overdues) == 0) { + $tickets = null; + } else { + $i = 0; + foreach ($overdues as $overdue) { + $sla_plan = Sla_plan::where('id', '=', $overdue->sla)->first(); + + $ovadate = $overdue->created_at; + $new_date = date_add($ovadate, date_interval_create_from_date_string($sla_plan->grace_period)).'

    '; + if (date('Y-m-d H:i:s') > $new_date) { + $i++; + $value[] = $overdue; + } + } + // dd(count($value)); + if ($i > 0) { + $tickets = new collection($value); + } else { + $tickets = null; + } + } + + return $this->getTable($tickets); + } + /** * Show the Closed ticket list page. * @@ -507,89 +212,7 @@ class TicketController extends Controller $tickets = Tickets::where('status', '>', 1)->where('dept_id', '=', $dept->id)->where('status', '<', 4)->get(); } - return \Datatable::collection(new Collection($tickets)) - ->addColumn('id', function ($ticket) { - return ""; - }) - ->addColumn('subject', function ($ticket) { - $subject = DB::table('ticket_thread')->select('title')->where('ticket_id', '=', $ticket->id)->first(); - if (isset($subject->title)) { - $string = $subject->title; - if (strlen($string) > 20) { - $stringCut = substr($string, 0, 30); - $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; - } - } else { - $string = '(no subject)'; - } - //collabrations - $collaborators = DB::table('ticket_collaborator')->where('ticket_id', '=', $ticket->id)->get(); - $collab = count($collaborators); - if ($collab > 0) { - $collabString = ' '; - } else { - $collabString = null; - } - $threads = Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); - $count = Ticket_Thread::where('ticket_id', '=', $ticket->id)->count(); - $attachment = Ticket_attachments::where('thread_id', '=', $threads->id)->get(); - $attachCount = count($attachment); - if ($attachCount > 0) { - $attachString = ' '; - } else { - $attachString = ''; - } - - return "id])."' title='".$subject->title."'>".$string." (".$count.")".$collabString.$attachString; - }) - ->addColumn('ticket_number', function ($ticket) { - return "id])."' title='".$ticket->ticket_number."'>#".$ticket->ticket_number.''; - }) - ->addColumn('priority', function ($ticket) { - $priority = DB::table('ticket_priority')->select('priority_desc', 'priority_color')->where('priority_id', '=', $ticket->priority_id)->first(); - - return ''.$priority->priority_desc.''; - }) - ->addColumn('from', function ($ticket) { - $from = DB::table('users')->select('user_name')->where('id', '=', $ticket->user_id)->first(); - - return "".$from->user_name.''; - }) - ->addColumn('Last Replier', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->where('is_internal', '!=', 1)->max('id'); - $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); - $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); - if ($LastResponse->role == 'user') { - $rep = '#F39C12'; - $username = $LastResponse->user_name; - } else { - $rep = '#000'; - $username = $LastResponse->first_name.' '.$LastResponse->last_name; - if ($LastResponse->first_name == null || $LastResponse->last_name == null) { - $username = $LastResponse->user_name; - } - } - - return "".$username.''; - }) - ->addColumn('assigned_to', function ($ticket) { - if ($ticket->assigned_to == null) { - return "Usernassigned"; - } else { - $assign = DB::table('users')->where('id', '=', $ticket->assigned_to)->first(); - - return "".$assign->first_name.' '.$assign->last_name.''; - } - }) - ->addColumn('Last', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = Ticket_Thread::select('updated_at')->where('id', '=', $TicketData)->first(); - - return UTC::usertimezone($TicketDatarow->updated_at); - }) - ->searchColumns('subject', 'from', 'assigned_to', 'ticket_number', 'priority') - ->orderColumns('subject', 'from', 'assigned_to', 'Last Replier', 'ticket_number', 'priority', 'Last') - ->make(); + return $this->getTable($tickets); } /** @@ -611,89 +234,7 @@ class TicketController extends Controller $tickets = Tickets::where('status', '=', 1)->where('assigned_to', '>', 0)->where('dept_id', '=', $dept->id)->get(); } - return \Datatable::collection(new Collection($tickets)) - ->addColumn('id', function ($ticket) { - return ""; - }) - ->addColumn('subject', function ($ticket) { - $subject = DB::table('ticket_thread')->select('title')->where('ticket_id', '=', $ticket->id)->first(); - if (isset($subject->title)) { - $string = $subject->title; - if (strlen($string) > 20) { - $stringCut = substr($string, 0, 30); - $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; - } - } else { - $string = '(no subject)'; - } - //collabrations - $collaborators = DB::table('ticket_collaborator')->where('ticket_id', '=', $ticket->id)->get(); - $collab = count($collaborators); - if ($collab > 0) { - $collabString = ' '; - } else { - $collabString = null; - } - $threads = Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); - $count = Ticket_Thread::where('ticket_id', '=', $ticket->id)->count(); - $attachment = Ticket_attachments::where('thread_id', '=', $threads->id)->get(); - $attachCount = count($attachment); - if ($attachCount > 0) { - $attachString = ' '; - } else { - $attachString = ''; - } - - return "id])."' title='".$subject->title."'>".$string." (".$count.")".$collabString.$attachString; - }) - ->addColumn('ticket_number', function ($ticket) { - return "id])."' title='".$ticket->ticket_number."'>#".$ticket->ticket_number.''; - }) - ->addColumn('priority', function ($ticket) { - $priority = DB::table('ticket_priority')->select('priority_desc', 'priority_color')->where('priority_id', '=', $ticket->priority_id)->first(); - - return ''.$priority->priority_desc.''; - }) - ->addColumn('from', function ($ticket) { - $from = DB::table('users')->select('user_name')->where('id', '=', $ticket->user_id)->first(); - - return "".$from->user_name.''; - }) - ->addColumn('Last Replier', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->where('is_internal', '!=', 1)->max('id'); - $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); - $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); - if ($LastResponse->role == 'user') { - $rep = '#F39C12'; - $username = $LastResponse->user_name; - } else { - $rep = '#000'; - $username = $LastResponse->first_name.' '.$LastResponse->last_name; - if ($LastResponse->first_name == null || $LastResponse->last_name == null) { - $username = $LastResponse->user_name; - } - } - - return "".$username.''; - }) - ->addColumn('assigned_to', function ($ticket) { - if ($ticket->assigned_to == null) { - return "Usernassigned"; - } else { - $assign = DB::table('users')->where('id', '=', $ticket->assigned_to)->first(); - - return "".$assign->first_name.' '.$assign->last_name.''; - } - }) - ->addColumn('Last', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = Ticket_Thread::select('updated_at')->where('id', '=', $TicketData)->first(); - - return UTC::usertimezone($TicketDatarow->updated_at); - }) - ->searchColumns('subject', 'from', 'assigned_to', 'ticket_number', 'priority') - ->orderColumns('subject', 'from', 'assigned_to', 'Last Replier', 'ticket_number', 'priority', 'Last') - ->make(); + return $this->getTable($tickets); } /** @@ -767,9 +308,12 @@ class TicketController extends Controller return redirect()->route('check_ticket', compact('ticket_id')); } + $avg = DB::table('ticket_thread')->where('ticket_id', '=', $id)->where('reply_rating', '!=', 0)->avg('reply_rating'); + $avg_rate = explode('.', $avg); + $avg_rating = $avg_rate[0]; $thread = Ticket_Thread::where('ticket_id', '=', $id)->first(); - return view('themes.default1.agent.helpdesk.ticket.timeline', compact('tickets'), compact('thread')); + return view('themes.default1.agent.helpdesk.ticket.timeline', compact('tickets'), compact('thread', 'avg_rating')); } /** @@ -874,6 +418,7 @@ class TicketController extends Controller $emails = Emails::where('department', '=', $tickets->dept_id)->first(); try { + $this->NotificationController->create($ticket_id, Auth::user()->id, '2'); $this->PhpMailController->sendmail( $from = $this->PhpMailController->mailfrom('0', $tickets->dept_id), $to = ['name' => $user_name, 'email' => $email, 'cc' => $collaborators], $message = ['subject' => $ticket_subject.'[#'.$ticket_number.']', 'body' => $request->input('reply_content'), 'scenario' => 'ticket-reply', 'attachments' => $attachment_files], $template_variables = ['ticket_number' => $ticket_number, 'user' => $username, 'agent_sign' => $agentsign] ); @@ -1003,7 +548,7 @@ class TicketController extends Controller * * @return type bool */ - public function create_user($emailadd, $username, $subject, $body, $phone, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $from_data, $auto_response) + public function create_user($emailadd, $username, $subject, $body, $phone, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $from_data, $auto_response, $status) { // define global variables $email; @@ -1044,7 +589,7 @@ class TicketController extends Controller $username = $checkemail->user_name; $user_id = $checkemail->id; } - $ticket_number = $this->check_ticket($user_id, $subject, $body, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $from_data); + $ticket_number = $this->check_ticket($user_id, $subject, $body, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $from_data, $status); $ticket_number2 = $ticket_number[0]; $ticketdata = Tickets::where('ticket_number', '=', $ticket_number2)->first(); $threaddata = Ticket_Thread::where('ticket_id', '=', $ticketdata->id)->first(); @@ -1175,7 +720,7 @@ class TicketController extends Controller * * @return type string */ - public function check_ticket($user_id, $subject, $body, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $form_data) + public function check_ticket($user_id, $subject, $body, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $form_data, $status) { $read_ticket_number = explode('[#', $subject); if (isset($read_ticket_number[1])) { @@ -1218,12 +763,12 @@ class TicketController extends Controller } } } else { - $ticket_number = $this->createTicket($user_id, $subject, $body, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $form_data); + $ticket_number = $this->createTicket($user_id, $subject, $body, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $form_data, $status); return [$ticket_number, 0]; } } else { - $ticket_number = $this->createTicket($user_id, $subject, $body, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $form_data); + $ticket_number = $this->createTicket($user_id, $subject, $body, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $form_data, $status); return [$ticket_number, 0]; } @@ -1241,7 +786,7 @@ class TicketController extends Controller * * @return type string */ - public function createTicket($user_id, $subject, $body, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $form_data) + public function createTicket($user_id, $subject, $body, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $form_data, $status) { $max_number = Tickets::whereRaw('id = (select max(`id`) from tickets)')->first(); if ($max_number == null) { @@ -1259,9 +804,14 @@ class TicketController extends Controller $ticket->help_topic_id = $helptopic; $ticket->sla = $sla; $ticket->assigned_to = $assignto; - $ticket->status = '1'; + $ticket->priority_id = $priority; $ticket->source = $source; + if ($status == null) { + $ticket->status = 1; + } else { + $ticket->status = $status; + } $ticket->save(); $sla_plan = Sla_plan::where('id', '=', $sla)->first(); @@ -1272,7 +822,7 @@ class TicketController extends Controller $ticket_number = $ticket->ticket_number; $id = $ticket->id; - + $this->NotificationController->create($id, $user_id, '3'); // store Form Data // Form Data comes from raising a ticket from client panel if ($form_data != null) { @@ -1407,7 +957,11 @@ class TicketController extends Controller $thread->ticket_id = $ticket_status->id; $thread->user_id = Auth::user()->id; $thread->is_internal = 1; - $thread->body = $ticket_status_message->message.' '.Auth::user()->first_name.' '.Auth::user()->last_name; + if (Auth::user()->first_name != null) { + $thread->body = $ticket_status_message->message.' '.Auth::user()->first_name.' '.Auth::user()->last_name; + } else { + $thread->body = $ticket_status_message->message.' '.Auth::user()->user_name; + } $thread->save(); return 'your ticket'.$ticket_status->ticket_number.' has been resolved'; @@ -1750,89 +1304,7 @@ class TicketController extends Controller $tickets = Tickets::where('status', '=', 5)->where('dept_id', '=', $dept->id)->get(); } - return \Datatable::collection(new Collection($tickets)) - ->addColumn('id', function ($ticket) { - return ""; - }) - ->addColumn('subject', function ($ticket) { - $subject = DB::table('ticket_thread')->select('title')->where('ticket_id', '=', $ticket->id)->first(); - if (isset($subject->title)) { - $string = $subject->title; - if (strlen($string) > 20) { - $stringCut = substr($string, 0, 30); - $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; - } - } else { - $string = '(no subject)'; - } - //collabrations - $collaborators = DB::table('ticket_collaborator')->where('ticket_id', '=', $ticket->id)->get(); - $collab = count($collaborators); - if ($collab > 0) { - $collabString = ' '; - } else { - $collabString = null; - } - $threads = Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); - $count = Ticket_Thread::where('ticket_id', '=', $ticket->id)->count(); - $attachment = Ticket_attachments::where('thread_id', '=', $threads->id)->get(); - $attachCount = count($attachment); - if ($attachCount > 0) { - $attachString = ' '; - } else { - $attachString = ''; - } - - return "id])."' title='".$subject->title."'>".$string." (".$count.")".$collabString.$attachString; - }) - ->addColumn('ticket_number', function ($ticket) { - return "id])."' title='".$ticket->ticket_number."'>#".$ticket->ticket_number.''; - }) - ->addColumn('priority', function ($ticket) { - $priority = DB::table('ticket_priority')->select('priority_desc', 'priority_color')->where('priority_id', '=', $ticket->priority_id)->first(); - - return ''.$priority->priority_desc.''; - }) - ->addColumn('from', function ($ticket) { - $from = DB::table('users')->select('user_name')->where('id', '=', $ticket->user_id)->first(); - - return "".$from->user_name.''; - }) - ->addColumn('Last Replier', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->where('is_internal', '!=', 1)->max('id'); - $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); - $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); - if ($LastResponse->role == 'user') { - $rep = '#F39C12'; - $username = $LastResponse->user_name; - } else { - $rep = '#000'; - $username = $LastResponse->first_name.' '.$LastResponse->last_name; - if ($LastResponse->first_name == null || $LastResponse->last_name == null) { - $username = $LastResponse->user_name; - } - } - - return "".$username.''; - }) - ->addColumn('assigned_to', function ($ticket) { - if ($ticket->assigned_to == null) { - return "Unassigned"; - } else { - $assign = DB::table('users')->where('id', '=', $ticket->assigned_to)->first(); - - return "".$assign->first_name.' '.$assign->last_name.''; - } - }) - ->addColumn('Last', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = Ticket_Thread::select('updated_at')->where('id', '=', $TicketData)->first(); - - return UTC::usertimezone($TicketDatarow->updated_at); - }) - ->searchColumns('subject', 'from', 'assigned_to', 'ticket_number', 'priority') - ->orderColumns('subject', 'from', 'assigned_to', 'Last Replier', 'ticket_number', 'priority', 'Last') - ->make(); + return $this->getTable($tickets); } /** @@ -1854,89 +1326,7 @@ class TicketController extends Controller $tickets = Tickets::where('assigned_to', '=', null)->where('dept_id', '=', $dept->id)->get(); } - return \Datatable::collection(new Collection($tickets)) - ->addColumn('id', function ($ticket) { - return ""; - }) - ->addColumn('subject', function ($ticket) { - $subject = DB::table('ticket_thread')->select('title')->where('ticket_id', '=', $ticket->id)->first(); - if (isset($subject->title)) { - $string = $subject->title; - if (strlen($string) > 20) { - $stringCut = substr($string, 0, 30); - $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; - } - } else { - $string = '(no subject)'; - } - //collabrations - $collaborators = DB::table('ticket_collaborator')->where('ticket_id', '=', $ticket->id)->get(); - $collab = count($collaborators); - if ($collab > 0) { - $collabString = ' '; - } else { - $collabString = null; - } - $threads = Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); - $count = Ticket_Thread::where('ticket_id', '=', $ticket->id)->count(); - $attachment = Ticket_attachments::where('thread_id', '=', $threads->id)->get(); - $attachCount = count($attachment); - if ($attachCount > 0) { - $attachString = ' '; - } else { - $attachString = ''; - } - - return "id])."' title='".$subject->title."'>".$string." (".$count.")".$collabString.$attachString; - }) - ->addColumn('ticket_number', function ($ticket) { - return "id])."' title='".$ticket->ticket_number."'>#".$ticket->ticket_number.''; - }) - ->addColumn('priority', function ($ticket) { - $priority = DB::table('ticket_priority')->select('priority_desc', 'priority_color')->where('priority_id', '=', $ticket->priority_id)->first(); - - return ''.$priority->priority_desc.''; - }) - ->addColumn('from', function ($ticket) { - $from = DB::table('users')->select('user_name')->where('id', '=', $ticket->user_id)->first(); - - return "".$from->user_name.''; - }) - ->addColumn('Last Replier', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->where('is_internal', '!=', 1)->max('id'); - $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); - $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); - if ($LastResponse->role == 'user') { - $rep = '#F39C12'; - $username = $LastResponse->user_name; - } else { - $rep = '#000'; - $username = $LastResponse->first_name.' '.$LastResponse->last_name; - if ($LastResponse->first_name == null || $LastResponse->last_name == null) { - $username = $LastResponse->user_name; - } - } - - return "".$username.''; - }) - ->addColumn('assigned_to', function ($ticket) { - if ($ticket->assigned_to == null) { - return "Unassigned"; - } else { - $assign = DB::table('users')->where('id', '=', $ticket->assigned_to)->first(); - - return "".$assign->first_name.' '.$assign->last_name.''; - } - }) - ->addColumn('Last', function ($ticket) { - $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = Ticket_Thread::select('updated_at')->where('id', '=', $TicketData)->first(); - - return UTC::usertimezone($TicketDatarow->updated_at); - }) - ->searchColumns('subject', 'from', 'assigned_to', 'ticket_number', 'priority') - ->orderColumns('subject', 'from', 'assigned_to', 'Last Replier', 'ticket_number', 'priority', 'Last') - ->make(); + return $this->getTable($tickets); } /** @@ -2015,9 +1405,9 @@ class TicketController extends Controller $ticket_collaborator->role = 'ccc'; $ticket_collaborator->save(); - return '

    Success!

    '.$data->user_name.'

    '.$data->email.'
    '; + return '

    Success!

    '.$data->user_name.'

    '.$data->email.'
    '; } else { - return '

    '.$data->user_name.'

    '.$data->email.'
    This user already Collaborated
    '; + return '

    '.$data->user_name.'

    '.$data->email.'
    This user already Collaborated
    '; } } @@ -2035,7 +1425,7 @@ class TicketController extends Controller $ticket_id = Input::get('ticket_id'); $user_search = User::where('email', '=', $email)->first(); if (isset($user_serach)) { - return '

    Alert!

    This user already Exists
    '; + return '

    Alert!

    This user already Exists
    '; } else { $company = $this->company(); $user = new User(); @@ -2057,7 +1447,7 @@ class TicketController extends Controller $ticket_collaborator->role = 'ccc'; $ticket_collaborator->save(); - return '

    '.$user->user_name.'

    '.$user->email.'
    '; + return '

    '.$user->user_name.'

    '.$user->email.'
    '; } } @@ -2100,8 +1490,34 @@ class TicketController extends Controller $ticket->reopened_at = date('Y-m-d H:i:s'); $ticket->closed = 0; $ticket->closed_at = null; - $ticket->save(); + } elseif ($value == 'Clean up') { + $thread = Ticket_Thread::where('ticket_id', '=', $ticket->id)->get(); + foreach ($thread as $th_id) { + // echo $th_id->id." "; + $attachment = Ticket_attachments::where('thread_id', '=', $th_id->id)->get(); + if (count($attachment)) { + foreach ($attachment as $a_id) { + echo $a_id->id.' '; + $attachment = Ticket_attachments::find($a_id->id); + $attachment->delete(); + } + // echo "
    "; + } + $thread = Ticket_Thread::find($th_id->id); +// dd($thread); + $thread->delete(); + } + $collaborators = Ticket_Collaborator::where('ticket_id', '=', $ticket->id)->get(); + if (count($collaborators)) { + foreach ($collaborators as $collab_id) { + echo $collab_id->id; + $collab = Ticket_Collaborator::find($collab_id->id); + $collab->delete(); + } + } + $tickets = Tickets::find($ticket->id); + $tickets->delete(); } } if ($value == 'Delete') { @@ -2110,6 +1526,8 @@ class TicketController extends Controller return redirect()->back()->with('success', 'Tickets has been Closed'); } elseif ($value == 'Open') { return redirect()->back()->with('success', 'Ticket has been Opened'); + } else { + return redirect()->back()->with('success', Lang::get('lang.hard-delete-success-message')); } } @@ -2137,6 +1555,34 @@ class TicketController extends Controller return $date; } + /** + *adding offset to updated_at time. + * + *@return date + */ + public static function timeOffset($utc) + { + $set = System::whereId('1')->first(); + $timezone = Timezones::whereId($set->time_zone)->first(); + $tz = $timezone->name; + date_default_timezone_set($tz); + $offset = date('Z', strtotime($utc)); + + return $offset; + } + + /** + * to get user date time format. + * + *@return string + */ + public static function getDateTimeFormat() + { + $set = System::select('date_time_format')->whereId('1')->first(); + + return $set->date_time_format; + } + /** * lock. * @@ -2228,8 +1674,15 @@ class TicketController extends Controller */ public function ratingReply($id, $rating) { - Tickets::where('id', $id)->update(['ratingreply' => $rating]); - + $thread = Ticket_Thread::whereId($id)->first(); +// $last_average = $thread->reply_rating; +//$total_numbers = $thread->rating_count; +//$new_number = $rating; +//$new_average = (($last_average * $total_numbers) + $new_number) / ($total_numbers + 1); +//$thread->rating_count += 1; +$thread->reply_rating = $rating; + $thread->save(); +// $thread->set('rating_count', 'rating_count+1', FALSE)->update(['ratingreply' => $new_average]); return redirect()->back()->with('Success', 'Thank you for your rating!'); } @@ -2489,7 +1942,7 @@ class TicketController extends Controller if (!empty(Input::get('reason'))) { $reason = Input::get('reason'); } else { - $reason = ''; + $reason = Lang::get('lang.no-reason'); } if (!empty(Input::get('title'))) { Ticket_thread::where('ticket_id', '=', $p_id)->first() @@ -2505,7 +1958,7 @@ class TicketController extends Controller $new_thread->title = $thread->title; $new_thread->body = Lang::get('lang.get_merge_message'). "  #".$parent_ticket->ticket_number.'
    '.$reason; + "'>#".$parent_ticket->ticket_number.'

    '.Lang::get('lang.merge-reason').''.$reason; $new_thread->format = $thread->format; $new_thread->ip_address = $thread->ip_address; @@ -2516,7 +1969,7 @@ class TicketController extends Controller $new_parent_thread->source = $parent_thread->source; $new_parent_thread->is_internal = 1; $new_parent_thread->title = $thread->title; - $new_parent_thread->body = Lang::get('lang.ticket')." #".$ticket->ticket_number.' '.Lang::get('lang.ticket_merged').'
    '.$reason; + $new_parent_thread->body = Lang::get('lang.ticket')." #".$ticket->ticket_number.' '.Lang::get('lang.ticket_merged').'

    '.Lang::get('lang.merge-reason').''.$reason; $new_parent_thread->format = $parent_thread->format; $new_parent_thread->ip_address = $parent_thread->ip_address; if ($new_thread->save() && $new_parent_thread->save()) { @@ -2539,4 +1992,111 @@ class TicketController extends Controller echo "'; } } + + /* + *chumper's function to return data to chumper datatable. + *@param Array-object $tickets + * + *@return Array-object + */ + public static function getTable($tickets) + { + return \Datatable::collection(new Collection($tickets)) + ->addColumn('id', function ($ticket) { + return ""; + }) + ->addColumn('subject', function ($ticket) { + $subject = DB::table('ticket_thread')->select('title')->where('ticket_id', '=', $ticket->id)->first(); + if (isset($subject->title)) { + $string = $subject->title; + if (strlen($string) > 20) { + $stringCut = substr($string, 0, 30); + $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; + } + } else { + $string = '(no subject)'; + } + //collabrations + $collaborators = DB::table('ticket_collaborator')->where('ticket_id', '=', $ticket->id)->get(); + $collab = count($collaborators); + if ($collab > 0) { + $collabString = ' '; + } else { + $collabString = null; + } + $threads = Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); // + $count = Ticket_Thread::where('ticket_id', '=', $ticket->id)->count(); // + $attachment = Ticket_attachments::where('thread_id', '=', $threads->id)->get(); + $attachCount = count($attachment); + if ($attachCount > 0) { + $attachString = ' '; + } else { + $attachString = ''; + } + + return "id])."' title='".$subject->title."'>".ucfirst($string)." (".$count.")".$collabString.$attachString; + }) + ->addColumn('ticket_number', function ($ticket) { + return "id])."' title='".$ticket->ticket_number."'>#".$ticket->ticket_number.''; + }) + ->addColumn('priority', function ($ticket) { + $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->where('is_internal', '=', 0)->max('id'); + $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); + $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); + if ($LastResponse->role == 'user') { + $rep = '#F39C12'; + $username = $LastResponse->user_name; + } else { + $rep = '#000'; + $username = $LastResponse->first_name.' '.$LastResponse->last_name; + if ($LastResponse->first_name == null || $LastResponse->last_name == null) { + $username = $LastResponse->user_name; + } + } + $priority = DB::table('ticket_priority')->select('priority_desc', 'priority_color')->where('priority_id', '=', $ticket->priority_id)->first(); + + return ''.ucfirst($priority->priority_desc).''; + }) + ->addColumn('from', function ($ticket) { + $from = DB::table('users')->select('user_name')->where('id', '=', $ticket->user_id)->first(); + + return "user_name).'''.Lang::get('lang.see-profile2')."'>".ucfirst($from->user_name).''; + }) + // ->addColumn('Last Replier', function ($ticket) { + // $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->where('is_internal', '=', 0)->max('id'); + // $TicketDatarow = Ticket_Thread::where('id', '=', $TicketData)->first(); + // $LastResponse = User::where('id', '=', $TicketDatarow->user_id)->first(); + // if ($LastResponse->role == 'user') { + // $rep = '#F39C12'; + // $username = $LastResponse->user_name; + // } else { + // $rep = '#000'; + // $username = $LastResponse->first_name.' '.$LastResponse->last_name; + // if ($LastResponse->first_name == null || $LastResponse->last_name == null) { + // $username = $LastResponse->user_name; + // } + // } + + // return "".ucfirst($username).''; + // }) + ->addColumn('assigned_to', function ($ticket) { + if ($ticket->assigned_to == null) { + return "Unassigned"; + } else { + $assign = DB::table('users')->where('id', '=', $ticket->assigned_to)->first(); + + return "first_name).'''.Lang::get('lang.see-profile2')."'>".ucfirst($assign->first_name).' '.ucfirst($assign->last_name).''; + } + }) + ->addColumn('Last', function ($ticket) { + $TicketData = Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); + $TicketDatarow = Ticket_Thread::select('updated_at')->where('id', '=', $TicketData)->first(); + + // return UTC::usertimezone($TicketDatarow->updated_at); + return date('Y-m-d H:i:s', strtotime($TicketDatarow->updated_at) + UTC::timeOffset($TicketDatarow->updated_at)); + }) + ->searchColumns('subject', 'from', 'assigned_to', 'ticket_number', 'priority') + ->orderColumns('subject', 'from', 'assigned_to', 'Last Replier', 'ticket_number', 'priority', 'Last') + ->make(); + } } diff --git a/app/Http/Controllers/Agent/helpdesk/TicketWorkflowController.php b/app/Http/Controllers/Agent/helpdesk/TicketWorkflowController.php new file mode 100644 index 000000000..93ed3f1f1 --- /dev/null +++ b/app/Http/Controllers/Agent/helpdesk/TicketWorkflowController.php @@ -0,0 +1,510 @@ + + */ +class TicketWorkflowController extends Controller +{ + /** + * constructor + * Create a new controller instance. + * + * @param type TicketController $TicketController + */ + public function __construct(TicketController $TicketController) + { + $this->TicketController = $TicketController; + } + + /** + * This is the core function from where the workflow is applied. + * + * @return type response + */ + public function workflow($fromaddress, $fromname, $subject, $body, $phone, $helptopic, $sla, $priority, $source, $collaborator, $dept, $assign, $team_assign, $ticket_status, $form_data, $auto_response) + { + $contact_details = ['email' => $fromaddress, 'email_name' => $fromname, 'subject' => $subject, 'message' => $body]; + $ticket_settings_details = ['help_topic' => $helptopic, 'sla' => $sla, 'priority' => $priority, 'source' => $source, 'dept' => $dept, 'assign' => $assign, 'team' => $team_assign, 'status' => $ticket_status, 'reject' => false]; + // get all the workflow common to the entire system which includes any type of ticket creation where the execution order of the workflow should be starting with ascending order + $workflows = WorkflowName::where('target', '=', 'A-0')->where('status', '=', '1')->orderBy('order', 'asc')->get(); + foreach ($workflows as $workflow) { + // checking if any workflow defined in the system + if ($workflow) { + // get all the rules of workflow which has a foreign key of those workflow which are applied to creating any ticket from any source + $worklfow_rules = WorkflowRules::where('workflow_id', '=', $workflow->id)->get(); + foreach ($worklfow_rules as $worklfow_rule) { + // checking for the workflow rules to which workflow rule type it is + if ($worklfow_rule->matching_scenario == 'email') { + if ($rule_condition = $this->checkRuleCondition($contact_details['email'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflow->id, $ticket_settings_details); + } + } elseif ($worklfow_rule->matching_scenario == 'email_name') { + if ($rule_condition = $this->checkRuleCondition($contact_details['email_name'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflow->id, $ticket_settings_details); + } + } elseif ($worklfow_rule->matching_scenario == 'subject') { + if ($rule_condition = $this->checkRuleCondition($contact_details['subject'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflow->id, $ticket_settings_details); + } + } elseif ($worklfow_rule->matching_scenario == 'message') { + if ($rule_condition = $this->checkRuleCondition($contact_details['message'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflow->id, $ticket_settings_details); + } + } + } + } + } + if ($source == 1) { + // get all the workflow which are applied to ticket generated via webforms and in ascending order + $workflows_webs = WorkflowName::where('target', '=', 'A-1')->where('status', '=', '1')->orderBy('order', 'asc')->get(); + foreach ($workflows_webs as $workflows_web) { + if ($workflows_web) { + $worklfow_rules = WorkflowRules::where('workflow_id', '=', $workflows_web->id)->get(); + foreach ($worklfow_rules as $worklfow_rule) { + if ($worklfow_rule) { + // checking for the workflow rules to which workflow rule type it is + if ($worklfow_rule->matching_scenario == 'email') { + if ($this->checkRuleCondition($contact_details['email'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflows_web->id, $ticket_settings_details); + } + } elseif ($worklfow_rule->matching_scenario == 'email_name') { + if ($this->checkRuleCondition($contact_details['email_name'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflows_web->id, $ticket_settings_details); + } + } elseif ($worklfow_rule->matching_scenario == 'subject') { + if ($this->checkRuleCondition($contact_details['subject'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflows_web->id, $ticket_settings_details); + } + } elseif ($worklfow_rule->matching_scenario == 'message') { + if ($this->checkRuleCondition($contact_details['message'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflows_web->id, $ticket_settings_details); + } + } + } + } + } + } + } + if ($source == 2) { + // get all the workflow which are applied to ticket generated via emails and in ascending order + $workflows_emails = WorkflowName::where('target', '=', 'A-2')->where('status', '=', '1')->orderBy('order', 'asc')->get(); + foreach ($workflows_emails as $workflows_email) { + if ($workflows_email) { + $worklfow_rules = WorkflowRules::where('workflow_id', '=', $workflows_email->id)->get(); + foreach ($worklfow_rules as $worklfow_rule) { + if ($worklfow_rule) { + // checking for the workflow rules to which workflow rule type it is + if ($worklfow_rule->matching_scenario == 'email') { + if ($rule_condition = $this->checkRuleCondition($contact_details['email'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflows_email->id, $ticket_settings_details); + } + } elseif ($worklfow_rule->matching_scenario == 'email_name') { + if ($rule_condition = $this->checkRuleCondition($contact_details['email_name'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflows_email->id, $ticket_settings_details); + } + } elseif ($worklfow_rule->matching_scenario == 'subject') { + if ($rule_condition = $this->checkRuleCondition($contact_details['subject'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflows_email->id, $ticket_settings_details); + } + } elseif ($worklfow_rule->matching_scenario == 'message') { + if ($rule_condition = $this->checkRuleCondition($contact_details['message'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflows_email->id, $ticket_settings_details); + } + } + } + } + } + } + } + if ($source == 4) { + // get all the workflow which are applied to ticket generated via API and in ascending order + $workflows_apis = WorkflowName::where('target', '=', 'A-4')->where('status', '=', '1')->orderBy('order', 'asc')->get(); + foreach ($workflows_apis as $workflows_api) { + if ($workflows_api) { + $worklfow_rules = WorkflowRules::where('workflow_id', '=', $workflows_api->id)->get(); + foreach ($worklfow_rules as $worklfow_rule) { + if ($worklfow_rule) { + // checking for the workflow rules to which workflow rule type it is + if ($worklfow_rule->matching_scenario == 'email') { + if ($rule_condition = $this->checkRuleCondition($contact_details['email'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflows_api->id, $ticket_settings_details); + } + } elseif ($worklfow_rule->matching_scenario == 'email_name') { + if ($rule_condition = $this->checkRuleCondition($contact_details['email_name'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflows_api->id, $ticket_settings_details); + } + } elseif ($worklfow_rule->matching_scenario == 'subject') { + if ($rule_condition = $this->checkRuleCondition($contact_details['subject'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflows_api->id, $ticket_settings_details); + } + } elseif ($worklfow_rule->matching_scenario == 'message') { + if ($rule_condition = $this->checkRuleCondition($contact_details['message'], $worklfow_rule->matching_relation, $worklfow_rule->matching_value) == true) { + $ticket_settings_details = $this->applyActionCondition($workflows_api->id, $ticket_settings_details); + } + } + } + } + } + } + } + if ($ticket_settings_details['reject'] == true) { + return ['0' => false, '1' => false]; + } else { + $create_ticket = $this->TicketController->create_user($contact_details['email'], $contact_details['email_name'], $contact_details['subject'], $contact_details['message'], $phone, $ticket_settings_details['help_topic'], $ticket_settings_details['sla'], $ticket_settings_details['priority'], $source, $collaborator, $ticket_settings_details['dept'], $ticket_settings_details['assign'], $form_data, $auto_response, $ticket_settings_details['status']); + + return $create_ticket; + } + } + + /** + * function to check the rules applied to the ticket workflow. + * + * @param type $to_check + * @param type $condition + * @param type $statement + * + * @return type boolean + */ + public function checkRuleCondition($to_check, $condition, $statement) + { + if ($condition == 'equal') { + $return = $this->checkEqual($statement, $to_check); + } elseif ($condition == 'not_equal') { + $return = $this->checkNotEqual($statement, $to_check); + } elseif ($condition == 'contains') { + $return = $this->checkContains($statement, $to_check); + } elseif ($condition == 'dn_contain') { + $return = $this->checkDoNotContain($statement, $to_check); + } elseif ($condition == 'starts') { + $return = $this->checkStarts($statement, $to_check); + } elseif ($condition == 'ends') { + $return = $this->checkEnds($statement, $to_check); + } +// elseif($condition == 'match') { +// +// } elseif($condition == 'not_match') { +// +// } + return $return; + } + + /** + * function to check if the equal functions are applied. + * + * @param type $statement + * @param type $to_check + * + * @return bool + */ + public function checkEqual($statement, $to_check) + { + if ($statement == $to_check) { + return true; + } else { + return false; + } + } + + /** + * function to check if the not-equal functions are applied. + * + * @param type $statement + * @param type $to_check + * + * @return bool + */ + public function checkNotEqual($statement, $to_check) + { + if ($statement != $to_check) { + return true; + } else { + return false; + } + } + + /** + * function to check if the contains functions are applied. + * + * @param type $statement + * @param type $to_check + * + * @return bool + */ + public function checkContains($statement, $to_check) + { + if (strpos($to_check, $statement) !== false) { + return true; + } else { + return false; + } + } + + /** + * function to check if the do not contain functions are applied. + * + * @param type $statement + * @param type $to_check + * + * @return bool + */ + public function checkDoNotContain($statement, $to_check) + { + if (strpos($to_check, $statement) == false) { + return true; + } else { + return false; + } + } + + /** + * function to check if the start functions are applied. + * + * @param type $statement + * @param type $to_check + * + * @return bool + */ + public function checkStarts($statement, $to_check) + { + if (substr($to_check, 0, strlen($statement)) == $statement) { + return true; + } else { + return false; + } + } + + /** + * function to check if the ends functions are applied. + * + * @param type $statement + * @param type $to_check + * + * @return bool + */ + public function checkEnds($statement, $to_check) + { + $to_check = strip_tags($to_check); + if (substr($to_check, -strlen($statement)) == $statement) { + return true; + } else { + return false; + } + } + +// function startsWith($to_check, $statement) { +// // search backwards starting from haystack length characters from the end +// return $statement === "" || strrpos($to_check, $statement, -strlen($to_check)) !== false; +// } + +// function endsWith($to_check, $statement) { +// // search forward starting from end minus needle length characters +// return $statement === "" || (($temp = strlen($to_check) - strlen($statement)) >= 0 && strpos($to_check, $statement, $temp) !== false); +// } + + /** + * function to apply the action to a ticket. + * + * @param type $workflow_id + * @param type $ticket_settings_details + * + * @return type array + */ + public function applyActionCondition($workflow_id, $ticket_settings_details) + { + $workflow_actions = WorkflowAction::where('workflow_id', '=', $workflow_id)->get(); + foreach ($workflow_actions as $workflow_action) { + if ($workflow_action->condition == 'reject') { + $ticket_settings_details = $this->rejectTicket($ticket_settings_details); + } elseif ($workflow_action->condition == 'department') { + $ticket_settings_details = $this->changeDepartment($workflow_action, $ticket_settings_details); + } elseif ($workflow_action->condition == 'priority') { + $ticket_settings_details = $this->changePriority($workflow_action, $ticket_settings_details); + } elseif ($workflow_action->condition == 'sla') { + $ticket_settings_details = $this->changeSla($workflow_action, $ticket_settings_details); + } elseif ($workflow_action->condition == 'team') { + $ticket_settings_details = $this->changeTeam($workflow_action, $ticket_settings_details); + } elseif ($workflow_action->condition == 'agent') { + $ticket_settings_details = $this->changeAgent($workflow_action, $ticket_settings_details); + } elseif ($workflow_action->condition == 'helptopic') { + $ticket_settings_details = $this->changeHelptopic($workflow_action, $ticket_settings_details); + } elseif ($workflow_action->condition == 'status') { + $ticket_settings_details = $this->changeStatus($workflow_action, $ticket_settings_details); + } + } + + return $ticket_settings_details; + } + + /** + * function to reject ticket. + * + * @param array $ticket_settings_details + * + * @return type array + */ + public function rejectTicket($ticket_settings_details) + { + $ticket_settings_details['reject'] = true; + + return $ticket_settings_details; + } + + /** + * function to change the department of a ticket. + * + * @param type $workflow_action + * @param type $ticket_settings_details + * + * @return type array + */ + public function changeDepartment($workflow_action, $ticket_settings_details) + { + $dept = Department::where('id', '=', $workflow_action->action)->first(); + if ($dept == null) { + return $ticket_settings_details; + } else { + $ticket_settings_details['dept'] = $dept->id; + + return $ticket_settings_details; + } + } + + /** + * function to change the priority of a ticket. + * + * @param type $workflow_action + * @param type $ticket_settings_details + * + * @return type array + */ + public function changePriority($workflow_action, $ticket_settings_details) + { + $priority = Ticket_Priority::where('priority_id', '=', $workflow_action->action)->first(); + if ($priority == null) { + return $ticket_settings_details; + } else { + $ticket_settings_details['priority'] = $priority->priority_id; + + return $ticket_settings_details; + } + } + + /** + * function to change the SLA of a ticket. + * + * @param type $workflow_action + * @param type $ticket_settings_details + * + * @return type array + */ + public function changeSla($workflow_action, $ticket_settings_details) + { + $sla_plan = Sla_plan::where('id', '=', $workflow_action->action)->first(); + if ($sla_plan == null) { + return $ticket_settings_details; + } else { + $ticket_settings_details['sla'] = $sla_plan->id; + + return $ticket_settings_details; + } + } + + /** + * function to assign tean to a ticket. + * + * @param type $workflow_action + * @param type $ticket_settings_details + * + * @return type array + */ + public function changeTeam($workflow_action, $ticket_settings_details) + { + $team = Teams::where('id', '=', $workflow_action->action)->first(); + if ($team == null) { + return $ticket_settings_details; + } else { + $ticket_settings_details['team'] = $team->id; + + return $ticket_settings_details; + } + } + + /** + * function to assing a ticket to an agent. + * + * @param type $workflow_action + * @param type $ticket_settings_details + * + * @return type array + */ + public function changeAgent($workflow_action, $ticket_settings_details) + { + $agent = User::where('id', '=', $workflow_action->action)->where('role', '!=', 'user')->first(); + if ($agent == null) { + return $ticket_settings_details; + } else { + $ticket_settings_details['assign'] = $agent->id; + + return $ticket_settings_details; + } + } + + /** + * function to change the helptopic of a ticket. + * + * @param type $workflow_action + * @param type $ticket_settings_details + * + * @return type array + */ + public function changeHelptopic($workflow_action, $ticket_settings_details) + { + $help_topic = Help_topic::where('id', '=', $workflow_action->action)->first(); + if ($help_topic == null) { + return $ticket_settings_details; + } else { + $ticket_settings_details['help_topic'] = $help_topic->id; + + return $ticket_settings_details; + } + } + + /** + * function to change the status of a ticket. + * + * @param type $workflow_action + * @param type $ticket_settings_details + * + * @return type array + */ + public function changeStatus($workflow_action, $ticket_settings_details) + { + $status = Ticket_Status::where('id', '=', $workflow_action->action)->first(); + if ($status == null) { + return $ticket_settings_details; + } else { + $ticket_settings_details['status'] = $status->id; + + return $ticket_settings_details; + } + } +} diff --git a/app/Http/Controllers/Agent/kb/SettingsController.php b/app/Http/Controllers/Agent/kb/SettingsController.php index 95d689ee9..8764b2f15 100644 --- a/app/Http/Controllers/Agent/kb/SettingsController.php +++ b/app/Http/Controllers/Agent/kb/SettingsController.php @@ -2,7 +2,8 @@ namespace App\Http\Controllers\Agent\kb; -// Controllersuse App\Http\Controllers\Agent\helpdesk\TicketController; +// Controllers +use App\Http\Controllers\Agent\helpdesk\TicketController; use App\Http\Controllers\Controller; // Request use App\Http\Requests\kb\ProfilePassword; diff --git a/app/Http/Controllers/Api/v1/ApiController.php b/app/Http/Controllers/Api/v1/ApiController.php index 91dab4449..d14daaa17 100644 --- a/app/Http/Controllers/Api/v1/ApiController.php +++ b/app/Http/Controllers/Api/v1/ApiController.php @@ -60,9 +60,12 @@ class ApiController extends Controller $this->middleware('jwt.auth'); $this->middleware('api', ['except' => 'GenerateApiKey']); - - $user = \JWTAuth::parseToken()->authenticate(); - $this->user = $user; + try { + $user = \JWTAuth::parseToken()->authenticate(); + $this->user = $user; + } catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $e) { + } catch (\Tymon\JWTAuth\Exceptions\JWTException $e) { + } $ticket = new TicketController(); $this->ticket = $ticket; @@ -82,6 +85,9 @@ class ApiController extends Controller $faveoUser = new User(); $this->faveoUser = $faveoUser; + $faveoUser = new User(); + $this->user = $faveoUser; + $team = new Teams(); $this->team = $team; @@ -138,18 +144,23 @@ class ApiController extends Controller $helptopic = $this->request->input('helptopic'); $sla = $this->request->input('sla'); $priority = $this->request->input('priority'); - $headers = $this->request->input('headers'); + $header = $this->request->input('cc'); $dept = $this->request->input('dept'); $assignto = $this->request->input('assignto'); $form_data = $this->request->input('form_data'); $source = $this->request->input('source'); $attach = $this->request->input('attachments'); + $headers = []; + if ($header) { + $headers = explode(',', $header); + } + //return $headers; /* * return s ticket number */ $response = $this->ticket->createTicket($user_id, $subject, $body, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $form_data, $attach); - + //return $response; /* * return ticket details */ @@ -166,7 +177,8 @@ class ApiController extends Controller } catch (\TokenExpiredException $e) { $error = $e->getMessage(); - return response()->json(compact('error')); + return response()->json(compact('error')) + ->header('Authenticate: xBasic realm', 'fake'); } } @@ -303,6 +315,7 @@ class ApiController extends Controller ->whereNotNull('title'); }) ->select('first_name', 'last_name', 'email', 'profile_pic', 'ticket_number', 'tickets.id', 'title', 'tickets.created_at', 'department.name as department_name', 'ticket_priority.priority as priotity_name', 'sla_plan.name as sla_plan_name', 'help_topic.topic as help_topic_name', 'ticket_status.name as ticket_status_name') + ->orderBy('ticket_thread.updated_at', 'desc') ->groupby('tickets.id') ->distinct() ->paginate(10) @@ -346,7 +359,8 @@ class ApiController extends Controller $join->on('tickets.id', '=', 'ticket_thread.ticket_id') ->whereNotNull('title'); }) - ->select('first_name', 'last_name', 'email', 'profile_pic', 'ticket_number', 'tickets.id', 'title', 'tickets.created_at', 'department.name as department_name', 'ticket_priority.priority as priotity_name', 'sla_plan.name as sla_plan_name', 'help_topic.topic as help_topic_name', 'ticket_status.name as ticket_status_name') + ->select('user_name', 'first_name', 'last_name', 'email', 'profile_pic', 'ticket_number', 'tickets.id', 'title', 'tickets.created_at', 'department.name as department_name', 'ticket_priority.priority as priotity_name', 'sla_plan.name as sla_plan_name', 'help_topic.topic as help_topic_name', 'ticket_status.name as ticket_status_name') + ->orderBy('ticket_thread.updated_at', 'desc') ->groupby('tickets.id') ->distinct() ->paginate(10) @@ -390,7 +404,8 @@ class ApiController extends Controller $join->on('tickets.id', '=', 'ticket_thread.ticket_id') ->whereNotNull('title'); }) - ->select('first_name', 'last_name', 'email', 'profile_pic', 'ticket_number', 'tickets.id', 'title', 'tickets.created_at', 'department.name as department_name', 'ticket_priority.priority as priotity_name', 'sla_plan.name as sla_plan_name', 'help_topic.topic as help_topic_name', 'ticket_status.name as ticket_status_name') + ->select('user_name', 'first_name', 'last_name', 'email', 'profile_pic', 'ticket_number', 'tickets.id', 'title', 'tickets.created_at', 'department.name as department_name', 'ticket_priority.priority as priotity_name', 'sla_plan.name as sla_plan_name', 'help_topic.topic as help_topic_name', 'ticket_status.name as ticket_status_name') + ->orderBy('ticket_thread.updated_at', 'desc') ->groupby('tickets.id') ->distinct() ->paginate(10) @@ -516,7 +531,8 @@ class ApiController extends Controller $search = $this->request->input('search'); $result = $this->faveoUser->where('first_name', 'like', '%'.$search.'%')->orWhere('last_name', 'like', '%'.$search.'%')->orWhere('user_name', 'like', '%'.$search.'%')->orWhere('email', 'like', '%'.$search.'%')->get(); - return response()->json(compact('result')); + return response()->json(compact('result')) + ->header('X-Header-One', 'Header Value'); } catch (Exception $e) { $error = $e->getMessage(); $line = $e->getLine(); @@ -526,7 +542,9 @@ class ApiController extends Controller } catch (\TokenExpiredException $e) { $error = $e->getMessage(); - return response()->json(compact('error')); + return response()->json(compact('error')) + + ->header('X-Header-One', 'Header Value'); } } @@ -538,26 +556,16 @@ class ApiController extends Controller public function getCustomersWith() { try { - $users = $this->faveoUser->select('id', 'user_name', 'first_name', 'last_name', 'email', 'phone_number', 'profile_pic')->where('role', 'user')->get(); - $result = []; - foreach ($users as $key => $user) { - $result[$key]['id'] = $user->id; - $result[$key]['user_name'] = $user->user_name; - $result[$key]['first_name'] = $user->first_name; - $result[$key]['last_name'] = $user->last_name; - $result[$key]['email'] = $user->email; - $result[$key]['phone_number'] = $user->phone_number; - if ($user->profile_pic) { - $path = 'lb-faveo/media/profilepic/'.$user->profile_pic; - } else { - $path = \Gravatar::src($user->email); - } - $result[$key]['picture'] = $path; - } - $result = $this->createPagination($result, 10); - //dd($result); - //$result->toJson(); - return $result->toJson(); + $users = $this->user + ->leftJoin('user_assign_organization', 'user_assign_organization.user_id', '=', 'users.id') + ->leftJoin('organization', 'organization.id', '=', 'user_assign_organization.org_id') + ->where('role', 'user') + ->select('users.id', 'user_name', 'first_name', 'last_name', 'email', 'phone_number', 'users.profile_pic', 'organization.name AS company', 'users.active') + ->paginate(10) + ->toJson(); + + //dd($users); + return $users; } catch (\Exception $e) { $error = $e->getMessage(); $line = $e->getLine(); @@ -567,7 +575,8 @@ class ApiController extends Controller } catch (\TokenExpiredException $e) { $error = $e->getMessage(); - return response()->json(compact('error')); + return response()->json(compact('error')) + ->header('Authenticate: xBasic realm', 'fake'); } } @@ -654,9 +663,14 @@ class ApiController extends Controller return response()->json(compact('error')); } $id = $this->request->input('id'); - $result = $this->thread->where('ticket_id', $id)->get(); + $result = $this->user + ->leftjoin('ticket_thread', 'ticket_thread.user_id', '=', 'users.id') + ->select('ticket_thread.id', 'ticket_id', 'user_id', 'poster', 'source', 'title', 'body', 'is_internal', 'format', 'ip_address', 'ticket_thread.created_at', 'ticket_thread.updated_at', 'users.first_name', 'users.last_name', 'users.user_name', 'users.email', 'users.profile_pic') + ->where('ticket_id', $id) + ->get() + ->toJson(); - return response()->json(compact('result')); + return $result; } catch (\Exception $e) { $error = $e->getMessage(); $line = $e->getLine(); @@ -689,6 +703,10 @@ class ApiController extends Controller } $url = $this->request->input('url'); + if (!str_is('*/', $url)) { + $url = str_finish($url, '/'); + } + $url = $url.'/api/v1/helpdesk/check-url?api_key='.$this->request->input('api_key').'&token='.\Config::get('app.token'); $result = $this->CallGetApi($url); //dd($result); @@ -903,7 +921,7 @@ class ApiController extends Controller public function getTickets() { try { - $tickets = $this->model->paginate(10); + $tickets = $this->model->orderBy('created_at', 'desc')->paginate(10); $tickets->toJson(); return $tickets; @@ -938,7 +956,8 @@ class ApiController extends Controller $join->on('tickets.id', '=', 'ticket_thread.ticket_id') ->whereNotNull('title'); }) - ->select('first_name', 'last_name', 'email', 'profile_pic', 'ticket_number', 'tickets.id', 'title', 'tickets.created_at', 'department.name as department_name', 'ticket_priority.priority as priotity_name', 'sla_plan.name as sla_plan_name', 'help_topic.topic as help_topic_name', 'ticket_status.name as ticket_status_name') + ->select('user_name', 'first_name', 'last_name', 'email', 'profile_pic', 'ticket_number', 'tickets.id', 'title', 'tickets.created_at', 'department.name as department_name', 'ticket_priority.priority as priotity_name', 'sla_plan.name as sla_plan_name', 'help_topic.topic as help_topic_name', 'ticket_status.name as ticket_status_name') + ->orderBy('ticket_thread.updated_at', 'desc') ->groupby('tickets.id') ->distinct() ->paginate(10) @@ -946,9 +965,9 @@ class ApiController extends Controller return $inbox; } catch (\Exception $ex) { - $error = $e->getMessage(); - $line = $e->getLine(); - $file = $e->getFile(); + $error = $ex->getMessage(); + $line = $ex->getLine(); + $file = $ex->getFile(); return response()->json(compact('error', 'file', 'line')); } catch (\TokenExpiredException $e) { @@ -1012,7 +1031,8 @@ class ApiController extends Controller $join->on('tickets.id', '=', 'ticket_thread.ticket_id') ->whereNotNull('title'); }) - ->select('first_name', 'last_name', 'email', 'profile_pic', 'ticket_number', 'tickets.id', 'title', 'tickets.created_at', 'department.name as department_name', 'ticket_priority.priority as priotity_name', 'sla_plan.name as sla_plan_name', 'help_topic.topic as help_topic_name', 'ticket_status.name as ticket_status_name') + ->select('user_name', 'first_name', 'last_name', 'email', 'profile_pic', 'ticket_number', 'tickets.id', 'title', 'tickets.created_at', 'department.name as department_name', 'ticket_priority.priority as priotity_name', 'sla_plan.name as sla_plan_name', 'help_topic.topic as help_topic_name', 'ticket_status.name as ticket_status_name') + ->orderBy('ticket_thread.updated_at', 'desc') ->groupby('tickets.id') ->distinct() ->paginate(10) @@ -1032,7 +1052,7 @@ class ApiController extends Controller } } - public function getMyTickets() + public function getMyTicketsAgent() { try { $v = \Validator::make($this->request->all(), [ @@ -1045,7 +1065,58 @@ class ApiController extends Controller } $id = $this->request->input('user_id'); if ($this->user->where('id', $id)->first()->role == 'user') { - $error = 'This user is not an Aget or Admin'; + $error = 'This user is not an Agent or Admin'; + + return response()->json(compact('error')); + } + $result = $this->user->join('tickets', function ($join) use ($id) { + $join->on('users.id', '=', 'tickets.assigned_to') + ->where('user_id', '=', $id); + }) + ->join('department', 'department.id', '=', 'tickets.dept_id') + ->join('ticket_priority', 'ticket_priority.priority_id', '=', 'tickets.priority_id') + ->join('sla_plan', 'sla_plan.id', '=', 'tickets.sla') + ->join('help_topic', 'help_topic.id', '=', 'tickets.help_topic_id') + ->join('ticket_status', 'ticket_status.id', '=', 'tickets.status') + ->join('ticket_thread', function ($join) { + $join->on('tickets.id', '=', 'ticket_thread.ticket_id') + ->whereNotNull('title'); + }) + ->select('user_name', 'first_name', 'last_name', 'email', 'profile_pic', 'ticket_number', 'tickets.id', 'title', 'tickets.created_at', 'department.name as department_name', 'ticket_priority.priority as priotity_name', 'sla_plan.name as sla_plan_name', 'help_topic.topic as help_topic_name', 'ticket_status.name as ticket_status_name') + ->orderBy('ticket_thread.updated_at', 'desc') + ->groupby('tickets.id') + ->distinct() + ->paginate(10) + ->toJson(); + + return $result; + } catch (\Exception $e) { + $error = $e->getMessage(); + $line = $e->getLine(); + $file = $e->getFile(); + + return response()->json(compact('error', 'file', 'line')); + } catch (\TokenExpiredException $e) { + $error = $e->getMessage(); + + return response()->json(compact('error')); + } + } + + public function getMyTicketsUser() + { + try { + $v = \Validator::make($this->request->all(), [ + 'user_id' => 'required|exists:users,id', + ]); + if ($v->fails()) { + $error = $v->errors(); + + return response()->json(compact('error')); + } + $id = $this->request->input('user_id'); + if ($this->user->where('id', $id)->first()->role == 'admin' || $this->user->where('id', $id)->first()->role == 'agent') { + $error = 'This is not a client'; return response()->json(compact('error')); } @@ -1062,10 +1133,12 @@ class ApiController extends Controller $join->on('tickets.id', '=', 'ticket_thread.ticket_id') ->whereNotNull('title'); }) - ->select('first_name', 'last_name', 'email', 'profile_pic', 'ticket_number', 'tickets.id', 'title', 'tickets.created_at', 'department.name as department_name', 'ticket_priority.priority as priotity_name', 'sla_plan.name as sla_plan_name', 'help_topic.topic as help_topic_name', 'ticket_status.name as ticket_status_name') + ->select('ticket_number', 'tickets.id', 'title', 'ticket_status.name as ticket_status_name') + ->orderBy('ticket_thread.updated_at', 'desc') ->groupby('tickets.id') ->distinct() - ->paginate(10) + ->get() + // ->paginate(10) ->toJson(); return $result; @@ -1143,4 +1216,160 @@ class ApiController extends Controller return response()->json(compact('error')); } } + + public function collaboratorSearch() + { + $this->validate($this->request, ['term' => 'required']); + try { + $emails = $this->ticket->autosearch(); + //return $emails; + $user = new User(); + if (count($emails) > 0) { + foreach ($emails as $key => $email) { + $user_model = $user->where('email', $email)->first(); + //return $user_model; + $users[$key]['name'] = $user_model->first_name.' '.$user_model->last_name; + $users[$key]['email'] = $email; + $users[$key]['avatar'] = $this->avatarUrl($email); + } + } + //return $users; + + return response()->json(compact('users')); + } catch (\Exception $e) { + $error = $e->getMessage(); + $line = $e->getLine(); + $file = $e->getFile(); + + return response()->json(compact('error', 'file', 'line')); + } + } + + public function avatarUrl($email) + { + try { + $user = new User(); + $user = $user->where('email', $email)->first(); + if ($user->profile_pic) { + $url = url('lb-faveo/media/profilepic/'.$user->profile_pic); + } else { + $url = \Gravatar::src($email); + } + + return $url; + } catch (\Exception $ex) { + //return $ex->getMessage(); + throw new \Exception($ex->getMessage()); + } + } + + public function addCollaboratorForTicket() + { + try { + $v = \Validator::make(\Input::get(), [ + 'email' => 'required|email|unique:users', + 'ticket_id' => 'required', + ] + ); + if ($v->fails()) { + $error = $v->messages(); + + return response()->json(compact('error')); + } + $collaborator = $this->ticket->useradd(); + + return response()->json(compact('collaborator')); + } catch (\Exception $e) { + $error = $e->getMessage(); + $line = $e->getLine(); + $file = $e->getFile(); + + return response()->json(compact('error', 'file', 'line')); + } catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $ex) { + $error = $e->getMessage(); + $line = $e->getLine(); + $file = $e->getFile(); + + return response()->json(compact('error', 'file', 'line')); + } + } + + public function getCollaboratorForTicket() + { + try { + $v = \Validator::make(\Input::get(), [ + 'ticket_id' => 'required', + ] + ); + if ($v->fails()) { + $error = $v->messages(); + + return response()->json(compact('error')); + } + $collaborator = $this->ticket->getCollaboratorForTicket(); + + return response()->json(compact('collaborator')); + } catch (\Exception $e) { + $error = $e->getMessage(); + $line = $e->getLine(); + $file = $e->getFile(); + + return response()->json(compact('error', 'file', 'line')); + } catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $ex) { + $error = $e->getMessage(); + $line = $e->getLine(); + $file = $e->getFile(); + + return response()->json(compact('error', 'file', 'line')); + } + } + + public function deleteCollaborator() + { + try { + $v = \Validator::make(\Input::get(), [ + 'ticketid' => 'required', + 'email' => 'required', + ] + ); + if ($v->fails()) { + $result = $v->messages(); + + return response()->json(compact('result')); + } + $collaborator = $this->ticket->userremove(); + + return response()->json(compact('collaborator')); + } catch (\Exception $ex) { + $error = $e->getMessage(); + $line = $e->getLine(); + $file = $e->getFile(); + + return response()->json(compact('error', 'file', 'line')); + } + } + + public function dependency() + { + try { + $department = $this->department->select('name', 'id')->get()->toArray(); + $sla = $this->slaPlan->select('name', 'id')->get()->toArray(); + $staff = $this->user->where('role', 'agent')->select('email', 'id')->get()->toArray(); + $team = $this->team->select('name', 'id')->get()->toArray(); + $priority = \DB::table('ticket_priority')->select('priority', 'priority_id')->get(); + $helptopic = $this->helptopic->select('topic', 'id')->get()->toArray(); + $status = \DB::table('ticket_status')->select('name', 'id')->get(); + $source = \DB::table('ticket_source')->select('name', 'id')->get(); + $result = ['departments' => $department, 'sla' => $sla, 'staffs' => $staff, 'teams' => $team, + 'priorities' => $priority, 'helptopics' => $helptopic, 'status' => $status, 'sources' => $source, ]; + + return response()->json(compact('result')); + } catch (\Exception $e) { + $error = $e->getMessage(); + $line = $e->getLine(); + $file = $e->getFile(); + + return response()->json(compact('error', 'file', 'line')); + } + } } diff --git a/app/Http/Controllers/Api/v1/ApiExceptAuthController.php b/app/Http/Controllers/Api/v1/ApiExceptAuthController.php index 9ade975b5..47a9b763f 100644 --- a/app/Http/Controllers/Api/v1/ApiExceptAuthController.php +++ b/app/Http/Controllers/Api/v1/ApiExceptAuthController.php @@ -12,7 +12,7 @@ class ApiExceptAuthController extends Controller public function __construct(Request $request) { $this->request = $request; - $this->middleware('api'); + //$this->middleware('api'); } /** @@ -34,7 +34,12 @@ class ApiExceptAuthController extends Controller } $url = $this->request->input('url'); - $url = $url.'/api/v1/helpdesk/check-url'; + if (!str_is('*/', $url)) { + $url = str_finish($url, '/'); + } + + $url = $url.'api/v1/helpdesk/check-url'; + //return $url; $result = $this->CallGetApi($url); // dd($result); return response()->json(compact('result')); diff --git a/app/Http/Controllers/Api/v1/TicketController.php b/app/Http/Controllers/Api/v1/TicketController.php index 079da83f7..67dbc8352 100644 --- a/app/Http/Controllers/Api/v1/TicketController.php +++ b/app/Http/Controllers/Api/v1/TicketController.php @@ -58,6 +58,7 @@ class TicketController extends Controller public function createTicket($user_id, $subject, $body, $helptopic, $sla, $priority, $source, $headers, $dept, $assignto, $form_data, $attach = '') { try { + //return $headers; $max_number = Tickets::whereRaw('id = (select max(`id`) from tickets)')->first(); //dd($max_number); if ($max_number == null) { @@ -97,7 +98,7 @@ class TicketController extends Controller } } } - + //return $headers; $this->storeCollaborators($headers, $id); $thread = $this->ticketThread($subject, $body, $id, $user_id); @@ -123,10 +124,11 @@ class TicketController extends Controller public function storeCollaborators($headers, $id) { try { + //return $headers; $company = $this->company(); if (isset($headers)) { - foreach ($headers as $email => $name) { - $name = $name; + foreach ($headers as $email) { + $name = $email; $email = $email; if ($this->checkEmail($email) == false) { $create_user = new User(); @@ -147,6 +149,7 @@ class TicketController extends Controller $user = $this->checkEmail($email); $user_id = $user->id; } + //return $user_id; $collaborator_store = new Ticket_Collaborator(); $collaborator_store->isactive = 1; $collaborator_store->ticket_id = $id; @@ -331,10 +334,10 @@ class TicketController extends Controller // // } // }, true); -try { - $this->PhpMailController->sendmail($from = $this->PhpMailController->mailfrom('0', $ticketdata->dept_id), $to = ['name' => $username, 'email' => $emailadd], $message = ['subject' => $updated_subject, 'scenario' => 'create-ticket-by-agent', 'body' => $body], $template_variables = ['agent_sign' => Auth::user()->agent_sign, 'ticket_number' => $ticket_number2]); -} catch (\Exception $e) { -} + try { + $this->PhpMailController->sendmail($from = $this->PhpMailController->mailfrom('0', $ticketdata->dept_id), $to = ['name' => $username, 'email' => $emailadd], $message = ['subject' => $updated_subject, 'scenario' => 'create-ticket-by-agent', 'body' => $body], $template_variables = ['agent_sign' => Auth::user()->agent_sign, 'ticket_number' => $ticket_number2]); + } catch (\Exception $e) { + } $collaborators = Ticket_Collaborator::where('ticket_id', '=', $ticket_id)->get(); foreach ($collaborators as $collaborator) { @@ -357,10 +360,10 @@ try { // // } // }, true); - try { - $this->PhpMailController->sendmail($from = $this->PhpMailController->mailfrom('0', $ticketdata->dept_id), $to = ['user' => $admin_user, 'email' => $admin_email], $message = ['subject' => $updated_subject, 'body' => $body, 'scenario' => $mail], $template_variables = ['ticket_agent_name' => $admin_user, 'ticket_client_name' => $username, 'ticket_client_email' => $emailadd, 'user' => $admin_user, 'ticket_number' => $ticket_number2, 'email_address' => $emailadd, 'name' => $ticket_creator]); - } catch (\Exception $e) { - } + try { + $this->PhpMailController->sendmail($from = $this->PhpMailController->mailfrom('0', $ticketdata->dept_id), $to = ['user' => $admin_user, 'email' => $admin_email], $message = ['subject' => $updated_subject, 'body' => $body, 'scenario' => $mail], $template_variables = ['ticket_agent_name' => $admin_user, 'ticket_client_name' => $username, 'ticket_client_email' => $emailadd, 'user' => $admin_user, 'ticket_number' => $ticket_number2, 'email_address' => $emailadd, 'name' => $ticket_creator]); + } catch (\Exception $e) { + } } return $thread; @@ -548,7 +551,7 @@ try { { try { $check = User::where('email', '=', $email)->first(); - if ($check == true) { + if ($check) { return $check; } else { return false; @@ -601,4 +604,123 @@ try { return $e->getMessage(); } } + + /** + * autosearch. + * + * @return type json + */ + public function autosearch() + { + $term = \Input::get('term'); + $user = \App\User::where('email', 'LIKE', '%'.$term.'%')->orWhere('first_name', 'LIKE', '%'.$term.'%')->orWhere('last_name', 'LIKE', '%'.$term.'%')->orWhere('user_name', 'LIKE', '%'.$term.'%')->lists('email'); + + return $user; + } + + /** + * useradd. + * + * @param type Image $image + * + * @return type json + */ + public function useradd() + { + $email = Input::get('email'); + $ticket_id = Input::get('ticket_id'); + $company = $this->company(); + $user = new User(); + $user->user_name = $email; + $user->email = $email; + $password = $this->generateRandomString(); + $user->password = \Hash::make($password); + $user->role = 'user'; + $user->active = 1; + if ($user->save()) { + $user_id = $user->id; + $php_mailer = new PhpMailController(); + $php_mailer->sendmail($from = $php_mailer->mailfrom('1', '0'), $to = ['name' => $email, 'email' => $email], $message = ['subject' => 'Password', 'scenario' => 'registration-notification'], $template_variables = ['user' => $email, 'email_address' => $email, 'user_password' => $password]); + } + $ticket_collaborator = new Ticket_Collaborator(); + $ticket_collaborator->isactive = 1; + $ticket_collaborator->ticket_id = $ticket_id; + $ticket_collaborator->user_id = $user->id; + $ticket_collaborator->role = 'ccc'; + $ticket_collaborator->save(); + + $result = [$user->user_name => $user->email]; + + return $result; + } + + /** + * user remove. + * + * @return type + */ + public function userremove() + { + $email = Input::get('email'); + $ticketid = Input::get('ticketid'); + $user = new User(); + $user = $user->where('email', $email)->first(); + $ticket_collaborator = Ticket_Collaborator::where('ticket_id', '=', $ticketid) + ->where('user_id', $user->id) + ->first(); + if ($ticket_collaborator) { + $ticket_collaborator->delete(); + + return 'deleted successfully'; + } else { + return 'not found'; + } + } + + public function getCollaboratorForTicket() + { + try { + $ticketid = Input::get('ticket_id'); + + $ticket_collaborator = \DB::table('users') + ->join('ticket_collaborator', function ($join) use ($ticketid) { + $join->on('users.id', '=', 'ticket_collaborator.user_id') + ->where('ticket_collaborator.ticket_id', '=', $ticketid); + }) + ->select('users.email', 'users.user_name') + ->get(); + if (count($ticket_collaborator) > 0) { + foreach ($ticket_collaborator as $key => $collaborator) { + $collab[$key]['email'] = $collaborator->email; + $collab[$key]['user_name'] = $collaborator->user_name; + $collab[$key]['avatar'] = $this->avatarUrl($collaborator->email); + } + } else { + $collab = $ticket_collaborator; + } + + return $collab; + } catch (\Exception $ex) { + return $ex->getMessage(); + throw new \Exception('get collaborator for ticket fails'); + } + } + + public function avatarUrl($email) + { + try { + $user = new User(); + $user = $user->where('email', $email)->first(); + if ($user->profile_pic) { + $url = url('lb-faveo/media/profilepic/'.$user->profile_pic); + } else { + $url = \Gravatar::src($email); + } + + return $url; + } catch (\Exception $ex) { + //return $ex->getMessage(); + throw new \Exception($ex->getMessage()); + } + } } diff --git a/app/Http/Controllers/Api/v1/TokenAuthController.php b/app/Http/Controllers/Api/v1/TokenAuthController.php index cf6fd00e6..d9bfe06cb 100644 --- a/app/Http/Controllers/Api/v1/TokenAuthController.php +++ b/app/Http/Controllers/Api/v1/TokenAuthController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Api\v1; +use App\Http\Controllers\Common\PhpMailController; use App\Http\Controllers\Controller; use App\User; use Illuminate\Http\Request; @@ -23,9 +24,14 @@ use Tymon\JWTAuth\Exceptions\JWTException; */ class TokenAuthController extends Controller { + public $PhpMailController; + public function __construct() { $this->middleware('api'); + + $PhpMailController = new PhpMailController(); + $this->PhpMailController = $PhpMailController; } /** @@ -41,7 +47,7 @@ class TokenAuthController extends Controller $password = $request->input('password'); $field = filter_var($usernameinput, FILTER_VALIDATE_EMAIL) ? 'email' : 'user_name'; - //$credentials = $request->only('email', 'password'); +//$credentials = $request->only('email', 'password'); try { if (!$token = JWTAuth::attempt([$field => $usernameinput, 'password' => $password])) { @@ -56,7 +62,7 @@ class TokenAuthController extends Controller } $user_id = \Auth::user()->id; - // if no errors are encountered we can return a JWT +// if no errors are encountered we can return a JWT return response()->json(compact('token', 'user_id')); } @@ -72,18 +78,18 @@ class TokenAuthController extends Controller if (!$user = JWTAuth::parseToken()->authenticate()) { return response()->json(['user_not_found', 404]); } - } catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $e) { + } catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $e) { return response()->json(['token_expired', $e->getStatusCode()]); - } catch (\Tymon\JWTAuth\Exceptions\TokenInvalidException $e) { + } catch (Tymon\JWTAuth\Exceptions\TokenInvalidException $e) { return response()->json(['token_invalid', $e->getStatusCode()]); - } catch (\Tymon\JWTAuth\Exceptions\JWTException $e) { + } catch (Tymon\JWTAuth\Exceptions\JWTException $e) { return response()->json(['token_absent', $e->getStatusCode()]); } catch (\Exception $e) { $error = $e->getMessage(); return response()->json(compact('error')); } - //dd($user); +//dd($user); return response()->json(compact('user')); } @@ -124,7 +130,7 @@ class TokenAuthController extends Controller * * @return type json */ - public function checkUrl() + public function checkUrl(Request $request) { try { $v = \Validator::make($request->all(), [ @@ -144,4 +150,43 @@ class TokenAuthController extends Controller return response()->json(compact('error')); } } + + public function forgotPassword(Request $request) + { + try { + $v = \Validator::make($request->all(), [ + 'email' => 'required|email|exists:users,email', + ]); + if ($v->fails()) { + $error = $v->errors(); + + return response()->json(compact('error')); + } + + $date = date('Y-m-d H:i:s'); + $user = User::where('email', '=', $request->only('email'))->first(); + if (isset($user)) { + $user1 = $user->email; + //gen new code and pass + $code = str_random(60); + $password_reset_table = \DB::table('password_resets')->where('email', '=', $user->email)->first(); + if (isset($password_reset_table)) { + $password_reset_table = \DB::table('password_resets')->where('email', '=', $user->email)->update(['token' => $code, 'created_at' => $date]); + // $password_reset_table->token = $code; + // $password_reset_table->update(['token' => $code]); + } else { + $create_password_reset = \DB::table('password_resets')->insert(['email' => $user->email, 'token' => $code, 'created_at' => $date]); + } + + $this->PhpMailController->sendmail($from = $this->PhpMailController->mailfrom('1', '0'), $to = ['name' => $user->user_name, 'email' => $user->email], $message = ['subject' => 'Your Password Reset Link', 'scenario' => 'reset-password'], $template_variables = ['user' => $user->user_name, 'email_address' => $user->email, 'password_reset_link' => url('password/reset/'.$code)]); + $result = 'We have e-mailed your password reset link!'; + + return response()->json(compact('result')); + } + } catch (Exception $ex) { + $error = $e->getMessage(); + + return response()->json(compact('error')); + } + } } diff --git a/app/Http/Controllers/Client/helpdesk/FormController.php b/app/Http/Controllers/Client/helpdesk/FormController.php index dd8c37a3b..544df7963 100644 --- a/app/Http/Controllers/Client/helpdesk/FormController.php +++ b/app/Http/Controllers/Client/helpdesk/FormController.php @@ -3,7 +3,7 @@ namespace App\Http\Controllers\Client\helpdesk; // controllers -use App\Http\Controllers\Agent\helpdesk\TicketController; +use App\Http\Controllers\Agent\helpdesk\TicketWorkflowController; use App\Http\Controllers\Common\SettingsController; use App\Http\Controllers\Controller; // requests @@ -14,6 +14,7 @@ use App\Model\helpdesk\Form\Fields; use App\Model\helpdesk\Manage\Help_topic; use App\Model\helpdesk\Settings\System; use App\Model\helpdesk\Settings\Ticket; +use App\Model\helpdesk\Ticket\Ticket_attachments; use App\Model\helpdesk\Ticket\Ticket_source; use App\Model\helpdesk\Ticket\Ticket_Thread; use App\Model\helpdesk\Ticket\Tickets; @@ -39,12 +40,12 @@ class FormController extends Controller * * @return void */ - public function __construct(TicketController $TicketController) + public function __construct(TicketWorkflowController $TicketWorkflowController) { // mail smtp settings - SettingsController::smtp(); +// SettingsController::smtp(); // creating a TicketController instance - $this->TicketController = $TicketController; + $this->TicketWorkflowController = $TicketWorkflowController; } /** @@ -129,7 +130,7 @@ class FormController extends Controller * @param type Request $request * @param type User $user */ - public function postedForm(User $user, ClientRequest $request, Ticket $ticket_settings, Ticket_source $ticket_source) + public function postedForm(User $user, ClientRequest $request, Ticket $ticket_settings, Ticket_source $ticket_source, Ticket_attachments $ta) { $form_extras = $request->except('Name', 'Phone', 'Email', 'Subject', 'Details', 'helptopic', '_wysihtml5_mode', '_token'); @@ -147,13 +148,33 @@ class FormController extends Controller $helptopic = $ticket_settings->first()->help_topic; $sla = $ticket_settings->first()->sla; $priority = $ticket_settings->first()->priority; - $source = $ticket_source->where('name', '=', 'web')->first(); + $source = $ticket_source->where('name', '=', 'web')->first()->id; + $attachments = $request->file('attachment'); $collaborator = null; $assignto = null; $auto_response = 0; - if ($this->TicketController->create_user($email, $name, $subject, $details, $phone, $helptopic, $sla, $priority, $source->id, $collaborator, $department, $assignto, $form_extras, $auto_response)) { - return Redirect::route('guest.getform')->with('success', 'Ticket Created Successfully'); + $team_assign = null; + + $result = $this->TicketWorkflowController->workflow($email, $name, $subject, $details, $phone, $helptopic, $sla, $priority, $source, $collaborator, $department, $assignto, $team_assign, $status, $form_extras, $auto_response); + + if ($result[1] == 1) { + $ticketId = Tickets::where('ticket_number', '=', $result[0])->first(); + $thread = Ticket_Thread::where('ticket_id', '=', $ticketId->id)->first(); + if ($attachments != null) { + foreach ($attachments as $attachment) { + if ($attachment != null) { + $name = $attachment->getClientOriginalName(); + $type = $attachment->getClientOriginalExtension(); + $size = $attachment->getSize(); + $data = file_get_contents($attachment->getRealPath()); + $attachPath = $attachment->getRealPath(); + $ta->create(['thread_id' => $thread->id, 'name' => $name, 'size' => $size, 'type' => $type, 'file' => $data, 'poster' => 'ATTACHMENT']); + } + } + } + + return Redirect::route('guest.getform')->with('success', 'Ticket has been created successfully, your ticket number is '.$result[0].' Please save this for future reference.'); } } diff --git a/app/Http/Controllers/Common/NotificationController.php b/app/Http/Controllers/Common/NotificationController.php new file mode 100644 index 000000000..14034e9d9 --- /dev/null +++ b/app/Http/Controllers/Common/NotificationController.php @@ -0,0 +1,83 @@ +user = $user; + } + + /** + * get the page to list the notifications. + * + * @return response + */ + public static function getNotifications() + { + $notifications = UserNotification::join('notifications', 'user_notification.notification_id', '=', 'notifications.id') + ->join('notification_types', 'notifications.type_id', '=', 'notification_types.id') + ->where('user_notification.is_read', '=', '0') + ->where('user_notification.user_id', '=', \Auth::user()->id) + ->get(); + + return $notifications; + } + + public function create($model_id, $userid_created, $type_id, $forwhome = []) + { + try { + if (empty($forwhome)) { + $forwhome = $this->user->where('role', '!=', 'user')->get()->toArray(); + } + //dd($forwhome); + //system notification + $notification = new Notification(); + $UN = new UserNotification(); + + $notify = $notification->create(['model_id' => $model_id, 'userid_created' => $userid_created, 'type_id' => $type_id]); + foreach ($forwhome as $agent) { + $user_notify = $UN->create(['notification_id' => $notify->id, 'user_id' => $agent['id'], 'is_read' => 0]); + } + } catch (\Exception $e) { + return redirect()->back()->with('fails', $e->getMessage()); + } + } + + public function markRead($id) + { + $markasread = UserNotification::where('notification_id', '=', $id)->where('user_id', '=', \Auth::user()->id)->where('is_read', '=', '0')->get(); + foreach ($markasread as $mark) { + $mark->is_read = '1'; + $mark->save(); + } + + return 1; + } + + public function show() + { + $notifications = $this->getNotifications(); + + return view('notifications-all', compact('notifications')); + } + + public function delete($id) + { + $markasread = UserNotification::where('notification_id', '=', $id)->where('user_id', '=', \Auth::user()->id)->get(); + foreach ($markasread as $mark) { + $mark->delete(); + } + + return 1; + } +} diff --git a/app/Http/Controllers/Common/SettingsController.php b/app/Http/Controllers/Common/SettingsController.php index a7206d3d4..266bcf1a7 100644 --- a/app/Http/Controllers/Common/SettingsController.php +++ b/app/Http/Controllers/Common/SettingsController.php @@ -414,7 +414,7 @@ class SettingsController extends Controller public function version_check() { $response_url = \URL::route('post-version-check'); - echo "
    "; + echo ""; echo ""; echo ""; echo ""; diff --git a/app/Http/Controllers/Installer/helpdesk/InstallController.php b/app/Http/Controllers/Installer/helpdesk/InstallController.php index cddca3257..6f7061991 100644 --- a/app/Http/Controllers/Installer/helpdesk/InstallController.php +++ b/app/Http/Controllers/Installer/helpdesk/InstallController.php @@ -298,7 +298,6 @@ class InstallController extends Controller // checking is the installation was done previously try { $check_for_pre_installation = System::all(); - dd($check_for_pre_installation); if ($check_for_pre_installation) { return redirect()->back()->with('fails', 'The data in database already exist. Please provide fresh database'); } diff --git a/app/Http/Requests/helpdesk/CompanyRequest.php b/app/Http/Requests/helpdesk/CompanyRequest.php index 21ce56665..a65751ee5 100644 --- a/app/Http/Requests/helpdesk/CompanyRequest.php +++ b/app/Http/Requests/helpdesk/CompanyRequest.php @@ -30,7 +30,7 @@ class CompanyRequest extends Request { return [ 'company_name' => 'required', - 'website' => 'url', + 'website' => 'active_url', 'phone' => 'numeric', 'logo' => 'image', ]; diff --git a/app/Http/Requests/helpdesk/OrganizationRequest.php b/app/Http/Requests/helpdesk/OrganizationRequest.php index ee74044ad..be88a915e 100644 --- a/app/Http/Requests/helpdesk/OrganizationRequest.php +++ b/app/Http/Requests/helpdesk/OrganizationRequest.php @@ -31,7 +31,7 @@ class OrganizationRequest extends Request return [ 'name' => 'required|unique:organization', - 'website' => 'url', + 'website' => 'active_url', // 'phone' => 'size:10', ]; } diff --git a/app/Http/Requests/helpdesk/OrganizationUpdate.php b/app/Http/Requests/helpdesk/OrganizationUpdate.php index 6d4ea4f12..4e5ef0a07 100644 --- a/app/Http/Requests/helpdesk/OrganizationUpdate.php +++ b/app/Http/Requests/helpdesk/OrganizationUpdate.php @@ -30,7 +30,7 @@ class OrganizationUpdate extends Request { return [ - 'website' => 'url', + 'website' => 'active_url', // 'phone' => 'size:10', ]; } diff --git a/app/Http/Requests/helpdesk/WorkflowCreateRequest.php b/app/Http/Requests/helpdesk/WorkflowCreateRequest.php new file mode 100644 index 000000000..a1ca0c207 --- /dev/null +++ b/app/Http/Requests/helpdesk/WorkflowCreateRequest.php @@ -0,0 +1,39 @@ + + */ +class WorkflowCreateRequest extends Request +{ + /** + * Determine if the user is authorized to make this request. + * + * @return bool + */ + public function authorize() + { + return true; + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + 'name' => 'required|unique:workflow_name,name', + 'execution_order' => 'required', + 'target_channel' => 'required', + 'rule' => 'required', + 'action' => 'required', + ]; + } +} diff --git a/app/Http/Requests/helpdesk/WorkflowUpdateRequest.php b/app/Http/Requests/helpdesk/WorkflowUpdateRequest.php new file mode 100644 index 000000000..f514e66e4 --- /dev/null +++ b/app/Http/Requests/helpdesk/WorkflowUpdateRequest.php @@ -0,0 +1,39 @@ + + */ +class WorkflowUpdateRequest extends Request +{ + /** + * Determine if the user is authorized to make this request. + * + * @return bool + */ + public function authorize() + { + return true; + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + 'name' => 'required', + 'execution_order' => 'required', + 'target_channel' => 'required', + 'rule' => 'required', + 'action' => 'required', + ]; + } +} diff --git a/app/Http/routes.php b/app/Http/routes.php index a44247b3a..36eeb2a9d 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -40,6 +40,14 @@ $router->get('getmail/{token}', 'Auth\AuthController@getMail'); | */ Route::group(['middleware' => 'roles', 'middleware' => 'auth'], function () { + + //Notification marking + Route::post('mark-read/{id}', 'Common\NotificationController@markRead'); + + Route::get('notifications-list', ['as' => 'notification.list', 'uses' => 'Common\NotificationController@show']); + + Route::post('notification-delete/{id}', ['as' => 'notification.delete', 'uses' => 'Common\NotificationController@delete']); + // resource is a function to process create,edit,read and delete Route::resource('groups', 'Admin\helpdesk\GroupController'); // for group module, for CRUD @@ -83,12 +91,18 @@ Route::group(['middleware' => 'roles', 'middleware' => 'auth'], function () { //$router->model('id','getcompany'); + Route::get('job-scheduler', ['as' => 'get.job.scheder', 'uses' => 'Admin\helpdesk\SettingsController@getSchedular']); //to get ob scheduler form page + + Route::patch('post-scheduler', ['as' => 'post.job.scheduler', 'uses' => 'Admin\helpdesk\SettingsController@postSchedular']); //to update job scheduler + Route::get('agent-profile-page/{id}', ['as' => 'agent.profile.page', 'uses' => 'Admin\helpdesk\AgentController@agent_profile']); Route::get('getcompany', 'Admin\helpdesk\SettingsController@getcompany'); // direct to company setting page Route::patch('postcompany/{id}', 'Admin\helpdesk\SettingsController@postcompany'); // Updating the Company table with requests + Route::get('delete-logo', ['as' => 'delete.logo', 'uses' => 'Admin\helpdesk\SettingsController@deleteLogo']); // deleting a logo + Route::get('getsystem', 'Admin\helpdesk\SettingsController@getsystem'); // direct to system setting page Route::patch('postsystem/{id}', 'Admin\helpdesk\SettingsController@postsystem'); // Updating the System table with requests @@ -183,6 +197,15 @@ Route::group(['middleware' => 'roles', 'middleware' => 'auth'], function () { Route::post('validating-email-settings', ['as' => 'validating.email.settings', 'uses' => 'Admin\helpdesk\EmailsController@validatingEmailSettings']); // route to check email input validation Route::post('validating-email-settings-on-update/{id}', ['as' => 'validating.email.settings.update', 'uses' => 'Admin\helpdesk\EmailsController@validatingEmailSettingsUpdate']); // route to check email input validation + + Route::get('workflow', ['as' => 'workflow', 'uses' => 'Admin\helpdesk\WorkflowController@index']); + Route::get('workflow-list', ['as' => 'workflow.list', 'uses' => 'Admin\helpdesk\WorkflowController@workFlowList']); + Route::get('workflow/create', ['as' => 'workflow.create', 'uses' => 'Admin\helpdesk\WorkflowController@create']); + Route::post('workflow/store', ['as' => 'workflow.store', 'uses' => 'Admin\helpdesk\WorkflowController@store']); + Route::get('workflow/edit/{id}', ['as' => 'workflow.edit', 'uses' => 'Admin\helpdesk\WorkflowController@edit']); + Route::post('workflow/update/{id}', ['as' => 'workflow.update', 'uses' => 'Admin\helpdesk\WorkflowController@update']); + Route::get('workflow/action-rule/{id}', ['as' => 'workflow.dept', 'uses' => 'Admin\helpdesk\WorkflowController@selectAction']); + Route::get('workflow/delete/{id}', ['as' => 'workflow.delete', 'uses' => 'Admin\helpdesk\WorkflowController@destroy']); }); /* @@ -257,6 +280,9 @@ Route::group(['middleware' => 'role.agent', 'middleware' => 'auth'], function () Route::get('/ticket/overdue', ['as' => 'overdue.ticket', 'uses' => 'Agent\helpdesk\TicketController@overdue_ticket_list']); /* Get Overdue Ticket */ + Route::get('/ticket/get-overdue', ['as' => 'get.overdue.ticket', + 'uses' => 'Agent\helpdesk\TicketController@getOverdueTickets', ]); + Route::get('/ticket/closed', ['as' => 'closed.ticket', 'uses' => 'Agent\helpdesk\TicketController@closed_ticket_list']); /* Get Closed Ticket */ Route::get('/ticket/get-closed', ['as' => 'get.closed.ticket', 'uses' => 'Agent\helpdesk\TicketController@get_closed']); /* Get tickets in datatable */ @@ -620,6 +646,7 @@ Route::get('/reportdata', 'HomeController@pushdata'); Route::group(['prefix' => 'api/v1'], function () { Route::post('register', 'Api\v1\TokenAuthController@register'); Route::post('authenticate', 'Api\v1\TokenAuthController@authenticate'); + Route::post('forgot', 'Api\v1\TokenAuthController@forgotPassword'); Route::get('authenticate/user', 'Api\v1\TokenAuthController@getAuthenticatedUser'); Route::get('/database-config', ['as' => 'database-config', 'uses' => 'Api\v1\InstallerApiController@config_database']); @@ -656,7 +683,7 @@ Route::group(['prefix' => 'api/v1'], function () { Route::get('ticket', 'Api\v1\ApiController@getTicketById'); Route::get('inbox', 'Api\v1\ApiController@inbox'); Route::get('trash', 'Api\v1\ApiController@getTrash'); - Route::get('my-tickets', 'Api\v1\ApiController@getMyTickets'); + Route::get('my-tickets-agent', 'Api\v1\ApiController@getMyTicketsAgent'); Route::post('internal-note', 'Api\v1\ApiController@internalNote'); /* @@ -664,6 +691,12 @@ Route::group(['prefix' => 'api/v1'], function () { */ Route::get('customers-custom', 'Api\v1\ApiController@getCustomersWith'); + Route::get('collaborator/search', 'Api\v1\ApiController@collaboratorSearch'); + Route::post('collaborator/create', 'Api\v1\ApiController@addCollaboratorForTicket'); + Route::post('collaborator/remove', 'Api\v1\ApiController@deleteCollaborator'); + Route::post('collaborator/get-ticket', 'Api\v1\ApiController@getCollaboratorForTicket'); + Route::get('my-tickets-user', 'Api\v1\ApiController@getMyTicketsUser'); + Route::get('dependency', 'Api\v1\ApiController@dependency'); }); /* diff --git a/app/Model/helpdesk/Agent/Groups.php b/app/Model/helpdesk/Agent/Groups.php index 086302e94..edcbaaecb 100644 --- a/app/Model/helpdesk/Agent/Groups.php +++ b/app/Model/helpdesk/Agent/Groups.php @@ -10,7 +10,7 @@ class Groups extends Model protected $fillable = [ 'name', 'group_status', 'can_create_ticket', 'can_edit_ticket', 'can_post_ticket', 'can_close_ticket', 'can_assign_ticket', - 'can_transfer_ticket', 'can_delete_ticket', 'can_ban_email', + 'can_delete_ticket', 'can_ban_email', 'can_manage_canned', 'can_manage_faq', 'can_view_agent_stats', 'department_access', 'admin_notes', ]; diff --git a/app/Model/helpdesk/Notification/Notification.php b/app/Model/helpdesk/Notification/Notification.php new file mode 100644 index 000000000..ba33bf5d4 --- /dev/null +++ b/app/Model/helpdesk/Notification/Notification.php @@ -0,0 +1,14 @@ +attach()->delete(); + $this->attach()->delete(); parent::delete(); } } diff --git a/app/Model/helpdesk/Workflow/WorkflowAction.php b/app/Model/helpdesk/Workflow/WorkflowAction.php new file mode 100644 index 000000000..2ad75f44b --- /dev/null +++ b/app/Model/helpdesk/Workflow/WorkflowAction.php @@ -0,0 +1,12 @@ +attributes['email']); + } else { + return asset('lb-faveo/media/profilepic/'.$value); + } + } } diff --git a/config/app.php b/config/app.php index ce6b22899..6b1a3d501 100644 --- a/config/app.php +++ b/config/app.php @@ -13,7 +13,7 @@ return [ | */ - 'debug' => true, + 'debug' => false, /* |-------------------------------------------------------------------------- @@ -38,7 +38,7 @@ return [ | */ - 'version' => 'Community 1.0.6.10', + 'version' => 'Community 1.0.7', /* |-------------------------------------------------------------------------- @@ -238,6 +238,7 @@ return [ 'PDF' => 'Vsmoraes\Pdf\PdfFacade', 'Gravatar' => 'Thomaswelton\LaravelGravatar\Facades\Gravatar', 'UTC' => 'App\Http\Controllers\Agent\helpdesk\TicketController', + 'Ttable' => 'App\Http\Controllers\Agent\helpdesk\TicketController', //to use getTable function. 'SMTPS' => 'App\Http\Controllers\HomeController', 'Datatable' => 'Chumper\Datatable\Facades\DatatableFacade', 'Zipper' => 'Chumper\Zipper\Zipper', diff --git a/config/lfm.php b/config/lfm.php index 6022fa66b..3e94eb37d 100644 --- a/config/lfm.php +++ b/config/lfm.php @@ -9,7 +9,7 @@ return [ 'shared_folder_name' => 'shares', 'thumb_folder_name' => 'thumbs', 'images_dir' => 'public/photos/', - 'images_url' => '%url%', //url('photos').'/', + 'images_url' => '%url%', 'files_dir' => 'public/files/', 'files_url' => '/files/', 'file_type_array' => [ diff --git a/database/migrations/2016_02_16_140450_create_ticket_thread_table.php b/database/migrations/2016_02_16_140450_create_ticket_thread_table.php index da7a53855..b7bf92e51 100644 --- a/database/migrations/2016_02_16_140450_create_ticket_thread_table.php +++ b/database/migrations/2016_02_16_140450_create_ticket_thread_table.php @@ -18,6 +18,8 @@ class CreateTicketThreadTable extends Migration $table->integer('user_id')->unsigned()->nullable()->index('user_id'); $table->string('poster'); $table->integer('source')->unsigned()->nullable()->index('source'); + $table->integer('reply_rating'); + $table->integer('rating_count'); $table->boolean('is_internal'); $table->string('title'); $table->text('body', 65535); diff --git a/database/migrations/2016_03_31_061239_create_notifications_table.php b/database/migrations/2016_03_31_061239_create_notifications_table.php new file mode 100644 index 000000000..0162b1211 --- /dev/null +++ b/database/migrations/2016_03_31_061239_create_notifications_table.php @@ -0,0 +1,33 @@ +increments('id'); + $table->integer('model_id'); + $table->integer('userid_created'); + $table->integer('type_id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('notifications'); + } +} diff --git a/database/migrations/2016_03_31_061534_create_notification_types_table.php b/database/migrations/2016_03_31_061534_create_notification_types_table.php new file mode 100644 index 000000000..8c5e1a08b --- /dev/null +++ b/database/migrations/2016_03_31_061534_create_notification_types_table.php @@ -0,0 +1,33 @@ +increments('id'); + $table->string('message'); + $table->string('type'); + $table->string('icon_class'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('notification_types'); + } +} diff --git a/database/migrations/2016_03_31_061740_create_user_notification_table.php b/database/migrations/2016_03_31_061740_create_user_notification_table.php new file mode 100644 index 000000000..b61a14574 --- /dev/null +++ b/database/migrations/2016_03_31_061740_create_user_notification_table.php @@ -0,0 +1,33 @@ +increments('id'); + $table->integer('notification_id'); + $table->integer('user_id'); + $table->integer('is_read'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('user_notification'); + } +} diff --git a/database/migrations/2016_04_18_115852_create_workflow_name_table.php b/database/migrations/2016_04_18_115852_create_workflow_name_table.php new file mode 100644 index 000000000..76a41fa2a --- /dev/null +++ b/database/migrations/2016_04_18_115852_create_workflow_name_table.php @@ -0,0 +1,35 @@ +increments('id'); + $table->string('name'); + $table->integer('status'); + $table->integer('order'); + $table->string('target'); + $table->text('internal_note'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('workflow_name'); + } +} diff --git a/database/migrations/2016_04_18_115900_create_workflow_rule_table.php b/database/migrations/2016_04_18_115900_create_workflow_rule_table.php new file mode 100644 index 000000000..7f0ca57c4 --- /dev/null +++ b/database/migrations/2016_04_18_115900_create_workflow_rule_table.php @@ -0,0 +1,42 @@ +increments('id'); + $table->integer('workflow_id')->unsigned(); + $table->string('matching_criteria'); + $table->string('matching_scenario'); + $table->string('matching_relation'); + $table->text('matching_value'); + $table->timestamps(); + }); + + Schema::table('workflow_rules', function (Blueprint $table) { + $table->foreign('workflow_id', 'workflow_rules_1')->references('id')->on('workflow_name')->onUpdate('NO ACTION')->onDelete('RESTRICT'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('workflow_rules', function (Blueprint $table) { + $table->dropForeign('workflow_rules_1'); + }); + Schema::drop('workflow_rules'); + } +} diff --git a/database/migrations/2016_04_18_115908_create_workflow_action_table.php b/database/migrations/2016_04_18_115908_create_workflow_action_table.php new file mode 100644 index 000000000..e27d00ffd --- /dev/null +++ b/database/migrations/2016_04_18_115908_create_workflow_action_table.php @@ -0,0 +1,39 @@ +increments('id'); + $table->integer('workflow_id')->unsigned(); + $table->string('condition'); + $table->string('action'); + $table->timestamps(); + }); + Schema::table('workflow_action', function (Blueprint $table) { + $table->foreign('workflow_id', 'workflow_action_1')->references('id')->on('workflow_name')->onUpdate('NO ACTION')->onDelete('RESTRICT'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('workflow_action'); + Schema::table('workflow_action', function (Blueprint $table) { + $table->dropForeign('workflow_action_idfk_1'); + }); + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 46a0f5dc3..776579992 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -196,10 +196,10 @@ class DatabaseSeeder extends Seeder Ticket_status::create(['name' => 'Archived', 'state' => 'archived', 'mode' => '3', 'message' => 'Ticket have been Archived by', 'flags' => '0', 'sort' => '4', 'properties' => 'Tickets only adminstratively available but no longer accessible on ticket queues and client panel.']); Ticket_status::create(['name' => 'Deleted', 'state' => 'deleted', 'mode' => '3', 'message' => 'Ticket have been Deleted by', 'flags' => '0', 'sort' => '5', 'properties' => 'Tickets queued for deletion. Not accessible on ticket queues.']); /* Ticket priority */ - Ticket_priority::create(['priority' => 'low', 'priority_desc' => 'Low', 'priority_color' => 'info', 'priority_urgency' => '4', 'ispublic' => '1']); - Ticket_priority::create(['priority' => 'normal', 'priority_desc' => 'Normal', 'priority_color' => 'info', 'priority_urgency' => '3', 'ispublic' => '1']); - Ticket_priority::create(['priority' => 'high', 'priority_desc' => 'High', 'priority_color' => 'warning', 'priority_urgency' => '2', 'ispublic' => '1']); - Ticket_priority::create(['priority' => 'emergency', 'priority_desc' => 'Emergency', 'priority_color' => 'danger', 'priority_urgency' => '1', 'ispublic' => '1']); + Ticket_priority::create(['priority' => 'Low', 'priority_desc' => 'Low', 'priority_color' => 'info', 'priority_urgency' => '4', 'ispublic' => '1']); + Ticket_priority::create(['priority' => 'Normal', 'priority_desc' => 'Normal', 'priority_color' => 'info', 'priority_urgency' => '3', 'ispublic' => '1']); + Ticket_priority::create(['priority' => 'High', 'priority_desc' => 'High', 'priority_color' => 'warning', 'priority_urgency' => '2', 'ispublic' => '1']); + Ticket_priority::create(['priority' => 'Emergency', 'priority_desc' => 'Emergency', 'priority_color' => 'danger', 'priority_urgency' => '1', 'ispublic' => '1']); /* SLA Plans */ Sla_plan::create(['name' => 'Sla 1', 'grace_period' => '6 Hours', 'status' => '1']); Sla_plan::create(['name' => 'Sla 2', 'grace_period' => '12 Hours', 'status' => '1']); diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 000000000..e69de29bb diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 000000000..067bd4be4 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,12 @@ + + + org.netbeans.modules.php.project + + + laravel + + + endif + + + diff --git a/public/css/notification-style.css b/public/css/notification-style.css new file mode 100644 index 000000000..3596d38c5 --- /dev/null +++ b/public/css/notification-style.css @@ -0,0 +1,22 @@ +.textcontent{ + display: inline-block; + padding-left: 5px; + font-weight: 600; + font-size: 14px; + font-family: 'Source Sans Pro','Helvetica Neue',Helvetica,Arial,sans-serif; +} +.task{ + opacity: 0.4; +} + +.task h6{ + text-decoration: line-through; +} + +.marginzero{ + margin: 0px; +} + +.font700{ + font-weight: 700; +} \ No newline at end of file diff --git a/public/downloads/en.zip b/public/downloads/en.zip index b6d455ea5..1bb3a7638 100644 Binary files a/public/downloads/en.zip and b/public/downloads/en.zip differ diff --git a/public/filemanager/connectors/php/plugins/rsc/cloudfiles.php b/public/filemanager/connectors/php/plugins/rsc/cloudfiles.php index acfa68c08..9870c6c1c 100644 --- a/public/filemanager/connectors/php/plugins/rsc/cloudfiles.php +++ b/public/filemanager/connectors/php/plugins/rsc/cloudfiles.php @@ -2317,4 +2317,4 @@ class CF_Object * c-basic-offset: 4 * c-hanging-comment-ender-p: nil * End: - */; + */ diff --git a/public/filemanager/connectors/php/plugins/rsc/cloudfiles_exceptions.php b/public/filemanager/connectors/php/plugins/rsc/cloudfiles_exceptions.php index 0f234b731..ef53aef8a 100644 --- a/public/filemanager/connectors/php/plugins/rsc/cloudfiles_exceptions.php +++ b/public/filemanager/connectors/php/plugins/rsc/cloudfiles_exceptions.php @@ -61,4 +61,4 @@ class ConnectionNotOpenException extends Exception * c-basic-offset: 4 * c-hanging-comment-ender-p: nil * End: - */; + */ diff --git a/public/filemanager/connectors/php/plugins/rsc/cloudfiles_http.php b/public/filemanager/connectors/php/plugins/rsc/cloudfiles_http.php index 00fa7b3e1..3a1c4ec5d 100644 --- a/public/filemanager/connectors/php/plugins/rsc/cloudfiles_http.php +++ b/public/filemanager/connectors/php/plugins/rsc/cloudfiles_http.php @@ -1454,4 +1454,4 @@ class CF_Http * c-basic-offset: 4 * c-hanging-comment-ender-p: nil * End: - */; + */ diff --git a/public/lb-faveo/css/faveo-css.css b/public/lb-faveo/css/faveo-css.css index 613be3f01..02c4c8cff 100644 --- a/public/lb-faveo/css/faveo-css.css +++ b/public/lb-faveo/css/faveo-css.css @@ -19,4 +19,39 @@ span.stars2, span.stars2 span { span.stars2 span { background-position: 0 0; } +.image { + position:relative; + +} +.image img { + width:100%; + vertical-align:top; +} +.image:after, .image:before { + position:absolute; + opacity:0; + transition: all 0.5s; + -webkit-transition: all 0.5s; +} +.image:after { + content:'\A'; + width:100%; height:100%; + top:0; left:0; + background:rgba(0,0,0,0.8); +} +.image:before { + content: attr(data-content); + width:80%; + color:#fff; + z-index:1; + bottom:40%; + padding:4px 10px; + text-align:center; + + box-sizing:border-box; + -moz-box-sizing:border-box; +} +.image:hover:after, .image:hover:before { + opacity:1; +} \ No newline at end of file diff --git a/public/lb-faveo/media/company/4477.faveo.png b/public/lb-faveo/media/company/4477.faveo.png new file mode 100644 index 000000000..b31d5938f Binary files /dev/null and b/public/lb-faveo/media/company/4477.faveo.png differ diff --git a/public/lb-faveo/plugins/moment/moment.js b/public/lb-faveo/plugins/moment/moment.js new file mode 100644 index 000000000..4124b5e09 --- /dev/null +++ b/public/lb-faveo/plugins/moment/moment.js @@ -0,0 +1,11412 @@ +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + global.moment = factory() +}(this, function () { 'use strict'; + + var hookCallback; + + function utils_hooks__hooks () { + return hookCallback.apply(null, arguments); + } + + // This is done to register the method called with moment() + // without creating circular dependencies. + function setHookCallback (callback) { + hookCallback = callback; + } + + function isArray(input) { + return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; + } + + function isDate(input) { + return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; + } + + function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); + } + return res; + } + + function hasOwnProp(a, b) { + return Object.prototype.hasOwnProperty.call(a, b); + } + + function extend(a, b) { + for (var i in b) { + if (hasOwnProp(b, i)) { + a[i] = b[i]; + } + } + + if (hasOwnProp(b, 'toString')) { + a.toString = b.toString; + } + + if (hasOwnProp(b, 'valueOf')) { + a.valueOf = b.valueOf; + } + + return a; + } + + function create_utc__createUTC (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, true).utc(); + } + + function defaultParsingFlags() { + // We need to deep clone this object. + return { + empty : false, + unusedTokens : [], + unusedInput : [], + overflow : -2, + charsLeftOver : 0, + nullInput : false, + invalidMonth : null, + invalidFormat : false, + userInvalidated : false, + iso : false + }; + } + + function getParsingFlags(m) { + if (m._pf == null) { + m._pf = defaultParsingFlags(); + } + return m._pf; + } + + function valid__isValid(m) { + if (m._isValid == null) { + var flags = getParsingFlags(m); + m._isValid = !isNaN(m._d.getTime()) && + flags.overflow < 0 && + !flags.empty && + !flags.invalidMonth && + !flags.invalidWeekday && + !flags.nullInput && + !flags.invalidFormat && + !flags.userInvalidated; + + if (m._strict) { + m._isValid = m._isValid && + flags.charsLeftOver === 0 && + flags.unusedTokens.length === 0 && + flags.bigHour === undefined; + } + } + return m._isValid; + } + + function valid__createInvalid (flags) { + var m = create_utc__createUTC(NaN); + if (flags != null) { + extend(getParsingFlags(m), flags); + } + else { + getParsingFlags(m).userInvalidated = true; + } + + return m; + } + + function isUndefined(input) { + return input === void 0; + } + + // Plugins that add properties should also add the key here (null value), + // so we can properly clone ourselves. + var momentProperties = utils_hooks__hooks.momentProperties = []; + + function copyConfig(to, from) { + var i, prop, val; + + if (!isUndefined(from._isAMomentObject)) { + to._isAMomentObject = from._isAMomentObject; + } + if (!isUndefined(from._i)) { + to._i = from._i; + } + if (!isUndefined(from._f)) { + to._f = from._f; + } + if (!isUndefined(from._l)) { + to._l = from._l; + } + if (!isUndefined(from._strict)) { + to._strict = from._strict; + } + if (!isUndefined(from._tzm)) { + to._tzm = from._tzm; + } + if (!isUndefined(from._isUTC)) { + to._isUTC = from._isUTC; + } + if (!isUndefined(from._offset)) { + to._offset = from._offset; + } + if (!isUndefined(from._pf)) { + to._pf = getParsingFlags(from); + } + if (!isUndefined(from._locale)) { + to._locale = from._locale; + } + + if (momentProperties.length > 0) { + for (i in momentProperties) { + prop = momentProperties[i]; + val = from[prop]; + if (!isUndefined(val)) { + to[prop] = val; + } + } + } + + return to; + } + + var updateInProgress = false; + + // Moment prototype object + function Moment(config) { + copyConfig(this, config); + this._d = new Date(config._d != null ? config._d.getTime() : NaN); + // Prevent infinite loop in case updateOffset creates new moment + // objects. + if (updateInProgress === false) { + updateInProgress = true; + utils_hooks__hooks.updateOffset(this); + updateInProgress = false; + } + } + + function isMoment (obj) { + return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); + } + + function absFloor (number) { + if (number < 0) { + return Math.ceil(number); + } else { + return Math.floor(number); + } + } + + function toInt(argumentForCoercion) { + var coercedNumber = +argumentForCoercion, + value = 0; + + if (coercedNumber !== 0 && isFinite(coercedNumber)) { + value = absFloor(coercedNumber); + } + + return value; + } + + // compare two arrays, return the number of differences + function compareArrays(array1, array2, dontConvert) { + var len = Math.min(array1.length, array2.length), + lengthDiff = Math.abs(array1.length - array2.length), + diffs = 0, + i; + for (i = 0; i < len; i++) { + if ((dontConvert && array1[i] !== array2[i]) || + (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { + diffs++; + } + } + return diffs + lengthDiff; + } + + function warn(msg) { + if (utils_hooks__hooks.suppressDeprecationWarnings === false && + (typeof console !== 'undefined') && console.warn) { + console.warn('Deprecation warning: ' + msg); + } + } + + function deprecate(msg, fn) { + var firstTime = true; + + return extend(function () { + if (firstTime) { + warn(msg + '\nArguments: ' + Array.prototype.slice.call(arguments).join(', ') + '\n' + (new Error()).stack); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); + } + + var deprecations = {}; + + function deprecateSimple(name, msg) { + if (!deprecations[name]) { + warn(msg); + deprecations[name] = true; + } + } + + utils_hooks__hooks.suppressDeprecationWarnings = false; + + function isFunction(input) { + return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; + } + + function isObject(input) { + return Object.prototype.toString.call(input) === '[object Object]'; + } + + function locale_set__set (config) { + var prop, i; + for (i in config) { + prop = config[i]; + if (isFunction(prop)) { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + this._config = config; + // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _ordinalParseLenient. + this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source); + } + + function mergeConfigs(parentConfig, childConfig) { + var res = extend({}, parentConfig), prop; + for (prop in childConfig) { + if (hasOwnProp(childConfig, prop)) { + if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { + res[prop] = {}; + extend(res[prop], parentConfig[prop]); + extend(res[prop], childConfig[prop]); + } else if (childConfig[prop] != null) { + res[prop] = childConfig[prop]; + } else { + delete res[prop]; + } + } + } + return res; + } + + function Locale(config) { + if (config != null) { + this.set(config); + } + } + + // internal storage for locale config files + var locales = {}; + var globalLocale; + + function normalizeLocale(key) { + return key ? key.toLowerCase().replace('_', '-') : key; + } + + // pick the locale from the array + // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each + // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root + function chooseLocale(names) { + var i = 0, j, next, locale, split; + + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + if (locale) { + return locale; + } + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; + } + return null; + } + + function loadLocale(name) { + var oldLocale = null; + // TODO: Find a better way to register and load all the locales in Node + if (!locales[name] && (typeof module !== 'undefined') && + module && module.exports) { + try { + oldLocale = globalLocale._abbr; + require('./locale/' + name); + // because defineLocale currently also sets the global locale, we + // want to undo that for lazy loaded locales + locale_locales__getSetGlobalLocale(oldLocale); + } catch (e) { } + } + return locales[name]; + } + + // This function will load locale and then set the global locale. If + // no arguments are passed in, it will simply return the current global + // locale key. + function locale_locales__getSetGlobalLocale (key, values) { + var data; + if (key) { + if (isUndefined(values)) { + data = locale_locales__getLocale(key); + } + else { + data = defineLocale(key, values); + } + + if (data) { + // moment.duration._locale = moment._locale = data; + globalLocale = data; + } + } + + return globalLocale._abbr; + } + + function defineLocale (name, config) { + if (config !== null) { + config.abbr = name; + if (locales[name] != null) { + deprecateSimple('defineLocaleOverride', + 'use moment.updateLocale(localeName, config) to change ' + + 'an existing locale. moment.defineLocale(localeName, ' + + 'config) should only be used for creating a new locale'); + config = mergeConfigs(locales[name]._config, config); + } else if (config.parentLocale != null) { + if (locales[config.parentLocale] != null) { + config = mergeConfigs(locales[config.parentLocale]._config, config); + } else { + // treat as if there is no base config + deprecateSimple('parentLocaleUndefined', + 'specified parentLocale is not defined yet'); + } + } + locales[name] = new Locale(config); + + // backwards compat for now: also set the locale + locale_locales__getSetGlobalLocale(name); + + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } + } + + function updateLocale(name, config) { + if (config != null) { + var locale; + if (locales[name] != null) { + config = mergeConfigs(locales[name]._config, config); + } + locale = new Locale(config); + locale.parentLocale = locales[name]; + locales[name] = locale; + + // backwards compat for now: also set the locale + locale_locales__getSetGlobalLocale(name); + } else { + // pass null for config to unupdate, useful for tests + if (locales[name] != null) { + if (locales[name].parentLocale != null) { + locales[name] = locales[name].parentLocale; + } else if (locales[name] != null) { + delete locales[name]; + } + } + } + return locales[name]; + } + + // returns locale data + function locale_locales__getLocale (key) { + var locale; + + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } + + if (!key) { + return globalLocale; + } + + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; + } + + return chooseLocale(key); + } + + function locale_locales__listLocales() { + return Object.keys(locales); + } + + var aliases = {}; + + function addUnitAlias (unit, shorthand) { + var lowerCase = unit.toLowerCase(); + aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; + } + + function normalizeUnits(units) { + return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; + } + + function normalizeObjectUnits(inputObject) { + var normalizedInput = {}, + normalizedProp, + prop; + + for (prop in inputObject) { + if (hasOwnProp(inputObject, prop)) { + normalizedProp = normalizeUnits(prop); + if (normalizedProp) { + normalizedInput[normalizedProp] = inputObject[prop]; + } + } + } + + return normalizedInput; + } + + function makeGetSet (unit, keepTime) { + return function (value) { + if (value != null) { + get_set__set(this, unit, value); + utils_hooks__hooks.updateOffset(this, keepTime); + return this; + } else { + return get_set__get(this, unit); + } + }; + } + + function get_set__get (mom, unit) { + return mom.isValid() ? + mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; + } + + function get_set__set (mom, unit, value) { + if (mom.isValid()) { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } + + // MOMENTS + + function getSet (units, value) { + var unit; + if (typeof units === 'object') { + for (unit in units) { + this.set(unit, units[unit]); + } + } else { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](value); + } + } + return this; + } + + function zeroFill(number, targetLength, forceSign) { + var absNumber = '' + Math.abs(number), + zerosToFill = targetLength - absNumber.length, + sign = number >= 0; + return (sign ? (forceSign ? '+' : '') : '-') + + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; + } + + var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; + + var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; + + var formatFunctions = {}; + + var formatTokenFunctions = {}; + + // token: 'M' + // padded: ['MM', 2] + // ordinal: 'Mo' + // callback: function () { this.month() + 1 } + function addFormatToken (token, padded, ordinal, callback) { + var func = callback; + if (typeof callback === 'string') { + func = function () { + return this[callback](); + }; + } + if (token) { + formatTokenFunctions[token] = func; + } + if (padded) { + formatTokenFunctions[padded[0]] = function () { + return zeroFill(func.apply(this, arguments), padded[1], padded[2]); + }; + } + if (ordinal) { + formatTokenFunctions[ordinal] = function () { + return this.localeData().ordinal(func.apply(this, arguments), token); + }; + } + } + + function removeFormattingTokens(input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|\]$/g, ''); + } + return input.replace(/\\/g, ''); + } + + function makeFormatFunction(format) { + var array = format.match(formattingTokens), i, length; + + for (i = 0, length = array.length; i < length; i++) { + if (formatTokenFunctions[array[i]]) { + array[i] = formatTokenFunctions[array[i]]; + } else { + array[i] = removeFormattingTokens(array[i]); + } + } + + return function (mom) { + var output = ''; + for (i = 0; i < length; i++) { + output += array[i] instanceof Function ? array[i].call(mom, format) : array[i]; + } + return output; + }; + } + + // format date using native date object + function formatMoment(m, format) { + if (!m.isValid()) { + return m.localeData().invalidDate(); + } + + format = expandFormat(format, m.localeData()); + formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); + + return formatFunctions[format](m); + } + + function expandFormat(format, locale) { + var i = 5; + + function replaceLongDateFormatTokens(input) { + return locale.longDateFormat(input) || input; + } + + localFormattingTokens.lastIndex = 0; + while (i >= 0 && localFormattingTokens.test(format)) { + format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); + localFormattingTokens.lastIndex = 0; + i -= 1; + } + + return format; + } + + var match1 = /\d/; // 0 - 9 + var match2 = /\d\d/; // 00 - 99 + var match3 = /\d{3}/; // 000 - 999 + var match4 = /\d{4}/; // 0000 - 9999 + var match6 = /[+-]?\d{6}/; // -999999 - 999999 + var match1to2 = /\d\d?/; // 0 - 99 + var match3to4 = /\d\d\d\d?/; // 999 - 9999 + var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 + var match1to3 = /\d{1,3}/; // 0 - 999 + var match1to4 = /\d{1,4}/; // 0 - 9999 + var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 + + var matchUnsigned = /\d+/; // 0 - inf + var matchSigned = /[+-]?\d+/; // -inf - inf + + var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z + var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z + + var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 + + // any word (or two) characters or numbers including two/three word month in arabic. + // includes scottish gaelic two word and hyphenated months + var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i; + + + var regexes = {}; + + function addRegexToken (token, regex, strictRegex) { + regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { + return (isStrict && strictRegex) ? strictRegex : regex; + }; + } + + function getParseRegexForToken (token, config) { + if (!hasOwnProp(regexes, token)) { + return new RegExp(unescapeFormat(token)); + } + + return regexes[token](config._strict, config._locale); + } + + // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript + function unescapeFormat(s) { + return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + })); + } + + function regexEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + } + + var tokens = {}; + + function addParseToken (token, callback) { + var i, func = callback; + if (typeof token === 'string') { + token = [token]; + } + if (typeof callback === 'number') { + func = function (input, array) { + array[callback] = toInt(input); + }; + } + for (i = 0; i < token.length; i++) { + tokens[token[i]] = func; + } + } + + function addWeekParseToken (token, callback) { + addParseToken(token, function (input, array, config, token) { + config._w = config._w || {}; + callback(input, config._w, config, token); + }); + } + + function addTimeToArrayFromToken(token, input, config) { + if (input != null && hasOwnProp(tokens, token)) { + tokens[token](input, config._a, config, token); + } + } + + var YEAR = 0; + var MONTH = 1; + var DATE = 2; + var HOUR = 3; + var MINUTE = 4; + var SECOND = 5; + var MILLISECOND = 6; + var WEEK = 7; + var WEEKDAY = 8; + + function daysInMonth(year, month) { + return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); + } + + // FORMATTING + + addFormatToken('M', ['MM', 2], 'Mo', function () { + return this.month() + 1; + }); + + addFormatToken('MMM', 0, 0, function (format) { + return this.localeData().monthsShort(this, format); + }); + + addFormatToken('MMMM', 0, 0, function (format) { + return this.localeData().months(this, format); + }); + + // ALIASES + + addUnitAlias('month', 'M'); + + // PARSING + + addRegexToken('M', match1to2); + addRegexToken('MM', match1to2, match2); + addRegexToken('MMM', function (isStrict, locale) { + return locale.monthsShortRegex(isStrict); + }); + addRegexToken('MMMM', function (isStrict, locale) { + return locale.monthsRegex(isStrict); + }); + + addParseToken(['M', 'MM'], function (input, array) { + array[MONTH] = toInt(input) - 1; + }); + + addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { + var month = config._locale.monthsParse(input, token, config._strict); + // if we didn't find a month name, mark the date as invalid. + if (month != null) { + array[MONTH] = month; + } else { + getParsingFlags(config).invalidMonth = input; + } + }); + + // LOCALES + + var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/; + var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); + function localeMonths (m, format) { + return isArray(this._months) ? this._months[m.month()] : + this._months[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; + } + + var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); + function localeMonthsShort (m, format) { + return isArray(this._monthsShort) ? this._monthsShort[m.month()] : + this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; + } + + function localeMonthsParse (monthName, format, strict) { + var i, mom, regex; + + if (!this._monthsParse) { + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + } + + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = create_utc__createUTC([2000, i]); + if (strict && !this._longMonthsParse[i]) { + this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); + this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); + } + if (!strict && !this._monthsParse[i]) { + regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); + this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { + return i; + } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { + return i; + } else if (!strict && this._monthsParse[i].test(monthName)) { + return i; + } + } + } + + // MOMENTS + + function setMonth (mom, value) { + var dayOfMonth; + + if (!mom.isValid()) { + // No op + return mom; + } + + if (typeof value === 'string') { + if (/^\d+$/.test(value)) { + value = toInt(value); + } else { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (typeof value !== 'number') { + return mom; + } + } + } + + dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; + } + + function getSetMonth (value) { + if (value != null) { + setMonth(this, value); + utils_hooks__hooks.updateOffset(this, true); + return this; + } else { + return get_set__get(this, 'Month'); + } + } + + function getDaysInMonth () { + return daysInMonth(this.year(), this.month()); + } + + var defaultMonthsShortRegex = matchWord; + function monthsShortRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsShortStrictRegex; + } else { + return this._monthsShortRegex; + } + } else { + return this._monthsShortStrictRegex && isStrict ? + this._monthsShortStrictRegex : this._monthsShortRegex; + } + } + + var defaultMonthsRegex = matchWord; + function monthsRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsStrictRegex; + } else { + return this._monthsRegex; + } + } else { + return this._monthsStrictRegex && isStrict ? + this._monthsStrictRegex : this._monthsRegex; + } + } + + function computeMonthsParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var shortPieces = [], longPieces = [], mixedPieces = [], + i, mom; + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = create_utc__createUTC([2000, i]); + shortPieces.push(this.monthsShort(mom, '')); + longPieces.push(this.months(mom, '')); + mixedPieces.push(this.months(mom, '')); + mixedPieces.push(this.monthsShort(mom, '')); + } + // Sorting makes sure if one month (or abbr) is a prefix of another it + // will match the longer piece. + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 12; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._monthsShortRegex = this._monthsRegex; + this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')$', 'i'); + this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')$', 'i'); + } + + function checkOverflow (m) { + var overflow; + var a = m._a; + + if (a && getParsingFlags(m).overflow === -2) { + overflow = + a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : + a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : + a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : + a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : + a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : + a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : + -1; + + if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { + overflow = DATE; + } + if (getParsingFlags(m)._overflowWeeks && overflow === -1) { + overflow = WEEK; + } + if (getParsingFlags(m)._overflowWeekday && overflow === -1) { + overflow = WEEKDAY; + } + + getParsingFlags(m).overflow = overflow; + } + + return m; + } + + // iso 8601 regex + // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) + var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/; + var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/; + + var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; + + var isoDates = [ + ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], + ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], + ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], + ['GGGG-[W]WW', /\d{4}-W\d\d/, false], + ['YYYY-DDD', /\d{4}-\d{3}/], + ['YYYY-MM', /\d{4}-\d\d/, false], + ['YYYYYYMMDD', /[+-]\d{10}/], + ['YYYYMMDD', /\d{8}/], + // YYYYMM is NOT allowed by the standard + ['GGGG[W]WWE', /\d{4}W\d{3}/], + ['GGGG[W]WW', /\d{4}W\d{2}/, false], + ['YYYYDDD', /\d{7}/] + ]; + + // iso time formats and regexes + var isoTimes = [ + ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], + ['HH:mm:ss', /\d\d:\d\d:\d\d/], + ['HH:mm', /\d\d:\d\d/], + ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], + ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], + ['HHmmss', /\d\d\d\d\d\d/], + ['HHmm', /\d\d\d\d/], + ['HH', /\d\d/] + ]; + + var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; + + // date from iso format + function configFromISO(config) { + var i, l, + string = config._i, + match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), + allowTime, dateFormat, timeFormat, tzFormat; + + if (match) { + getParsingFlags(config).iso = true; + + for (i = 0, l = isoDates.length; i < l; i++) { + if (isoDates[i][1].exec(match[1])) { + dateFormat = isoDates[i][0]; + allowTime = isoDates[i][2] !== false; + break; + } + } + if (dateFormat == null) { + config._isValid = false; + return; + } + if (match[3]) { + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(match[3])) { + // match[2] should be 'T' or space + timeFormat = (match[2] || ' ') + isoTimes[i][0]; + break; + } + } + if (timeFormat == null) { + config._isValid = false; + return; + } + } + if (!allowTime && timeFormat != null) { + config._isValid = false; + return; + } + if (match[4]) { + if (tzRegex.exec(match[4])) { + tzFormat = 'Z'; + } else { + config._isValid = false; + return; + } + } + config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); + configFromStringAndFormat(config); + } else { + config._isValid = false; + } + } + + // date from iso format or fallback + function configFromString(config) { + var matched = aspNetJsonRegex.exec(config._i); + + if (matched !== null) { + config._d = new Date(+matched[1]); + return; + } + + configFromISO(config); + if (config._isValid === false) { + delete config._isValid; + utils_hooks__hooks.createFromInputFallback(config); + } + } + + utils_hooks__hooks.createFromInputFallback = deprecate( + 'moment construction falls back to js Date. This is ' + + 'discouraged and will be removed in upcoming major ' + + 'release. Please refer to ' + + 'https://github.com/moment/moment/issues/1407 for more info.', + function (config) { + config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + } + ); + + function createDate (y, m, d, h, M, s, ms) { + //can't just apply() to create a date: + //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply + var date = new Date(y, m, d, h, M, s, ms); + + //the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getFullYear())) { + date.setFullYear(y); + } + return date; + } + + function createUTCDate (y) { + var date = new Date(Date.UTC.apply(null, arguments)); + + //the Date.UTC function remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) { + date.setUTCFullYear(y); + } + return date; + } + + // FORMATTING + + addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? '' + y : '+' + y; + }); + + addFormatToken(0, ['YY', 2], 0, function () { + return this.year() % 100; + }); + + addFormatToken(0, ['YYYY', 4], 0, 'year'); + addFormatToken(0, ['YYYYY', 5], 0, 'year'); + addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); + + // ALIASES + + addUnitAlias('year', 'y'); + + // PARSING + + addRegexToken('Y', matchSigned); + addRegexToken('YY', match1to2, match2); + addRegexToken('YYYY', match1to4, match4); + addRegexToken('YYYYY', match1to6, match6); + addRegexToken('YYYYYY', match1to6, match6); + + addParseToken(['YYYYY', 'YYYYYY'], YEAR); + addParseToken('YYYY', function (input, array) { + array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input); + }); + addParseToken('YY', function (input, array) { + array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input); + }); + addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); + }); + + // HELPERS + + function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; + } + + function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; + } + + // HOOKS + + utils_hooks__hooks.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + }; + + // MOMENTS + + var getSetYear = makeGetSet('FullYear', false); + + function getIsLeapYear () { + return isLeapYear(this.year()); + } + + // start-of-first-week - start-of-year + function firstWeekOffset(year, dow, doy) { + var // first-week day -- which january is always in the first week (4 for iso, 1 for other) + fwd = 7 + dow - doy, + // first-week day local weekday -- which local weekday is fwd + fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; + + return -fwdlw + fwd - 1; + } + + //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday + function dayOfYearFromWeeks(year, week, weekday, dow, doy) { + var localWeekday = (7 + weekday - dow) % 7, + weekOffset = firstWeekOffset(year, dow, doy), + dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, + resYear, resDayOfYear; + + if (dayOfYear <= 0) { + resYear = year - 1; + resDayOfYear = daysInYear(resYear) + dayOfYear; + } else if (dayOfYear > daysInYear(year)) { + resYear = year + 1; + resDayOfYear = dayOfYear - daysInYear(year); + } else { + resYear = year; + resDayOfYear = dayOfYear; + } + + return { + year: resYear, + dayOfYear: resDayOfYear + }; + } + + function weekOfYear(mom, dow, doy) { + var weekOffset = firstWeekOffset(mom.year(), dow, doy), + week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, + resWeek, resYear; + + if (week < 1) { + resYear = mom.year() - 1; + resWeek = week + weeksInYear(resYear, dow, doy); + } else if (week > weeksInYear(mom.year(), dow, doy)) { + resWeek = week - weeksInYear(mom.year(), dow, doy); + resYear = mom.year() + 1; + } else { + resYear = mom.year(); + resWeek = week; + } + + return { + week: resWeek, + year: resYear + }; + } + + function weeksInYear(year, dow, doy) { + var weekOffset = firstWeekOffset(year, dow, doy), + weekOffsetNext = firstWeekOffset(year + 1, dow, doy); + return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; + } + + // Pick the first defined of two or three arguments. + function defaults(a, b, c) { + if (a != null) { + return a; + } + if (b != null) { + return b; + } + return c; + } + + function currentDateArray(config) { + // hooks is actually the exported moment object + var nowValue = new Date(utils_hooks__hooks.now()); + if (config._useUTC) { + return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; + } + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; + } + + // convert an array to a date. + // the array should mirror the parameters below + // note: all values past the year are optional and will default to the lowest possible value. + // [year, month, day , hour, minute, second, millisecond] + function configFromArray (config) { + var i, date, input = [], currentDate, yearToUse; + + if (config._d) { + return; + } + + currentDate = currentDateArray(config); + + //compute day of the year from weeks and weekdays + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } + + //if the day of the year is set, figure out what it is + if (config._dayOfYear) { + yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); + + if (config._dayOfYear > daysInYear(yearToUse)) { + getParsingFlags(config)._overflowDayOfYear = true; + } + + date = createUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } + + // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; + } + + // Zero out whatever was not defaulted, including time + for (; i < 7; i++) { + config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; + } + + // Check for 24:00:00.000 + if (config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } + + config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); + // Apply timezone offset from input. The actual utcOffset can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; + } + } + + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year); + week = defaults(w.W, 1); + weekday = defaults(w.E, 1); + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year); + week = defaults(w.w, 1); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; + } + } else if (w.e != null) { + // local weekday -- counting starts from begining of week + weekday = w.e + dow; + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } + } else { + // default to begining of week + weekday = dow; + } + } + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } + } + + // constant that refers to the ISO standard + utils_hooks__hooks.ISO_8601 = function () {}; + + // date from string and format string + function configFromStringAndFormat(config) { + // TODO: Move this to another part of the creation flow to prevent circular deps + if (config._f === utils_hooks__hooks.ISO_8601) { + configFromISO(config); + return; + } + + config._a = []; + getParsingFlags(config).empty = true; + + // This array is used to make a Date, either with `new Date` or `Date.UTC` + var string = '' + config._i, + i, parsedInput, tokens, token, skipped, + stringLength = string.length, + totalParsedInputLength = 0; + + tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; + + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; + // console.log('token', token, 'parsedInput', parsedInput, + // 'regex', getParseRegexForToken(token, config)); + if (parsedInput) { + skipped = string.substr(0, string.indexOf(parsedInput)); + if (skipped.length > 0) { + getParsingFlags(config).unusedInput.push(skipped); + } + string = string.slice(string.indexOf(parsedInput) + parsedInput.length); + totalParsedInputLength += parsedInput.length; + } + // don't parse if it's not a known token + if (formatTokenFunctions[token]) { + if (parsedInput) { + getParsingFlags(config).empty = false; + } + else { + getParsingFlags(config).unusedTokens.push(token); + } + addTimeToArrayFromToken(token, parsedInput, config); + } + else if (config._strict && !parsedInput) { + getParsingFlags(config).unusedTokens.push(token); + } + } + + // add remaining unparsed input length to the string + getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; + if (string.length > 0) { + getParsingFlags(config).unusedInput.push(string); + } + + // clear _12h flag if hour is <= 12 + if (getParsingFlags(config).bigHour === true && + config._a[HOUR] <= 12 && + config._a[HOUR] > 0) { + getParsingFlags(config).bigHour = undefined; + } + // handle meridiem + config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); + + configFromArray(config); + checkOverflow(config); + } + + + function meridiemFixWrap (locale, hour, meridiem) { + var isPm; + + if (meridiem == null) { + // nothing to do + return hour; + } + if (locale.meridiemHour != null) { + return locale.meridiemHour(hour, meridiem); + } else if (locale.isPM != null) { + // Fallback + isPm = locale.isPM(meridiem); + if (isPm && hour < 12) { + hour += 12; + } + if (!isPm && hour === 12) { + hour = 0; + } + return hour; + } else { + // this is not supposed to happen + return hour; + } + } + + // date from string and array of format strings + function configFromStringAndArray(config) { + var tempConfig, + bestMoment, + + scoreToBeat, + i, + currentScore; + + if (config._f.length === 0) { + getParsingFlags(config).invalidFormat = true; + config._d = new Date(NaN); + return; + } + + for (i = 0; i < config._f.length; i++) { + currentScore = 0; + tempConfig = copyConfig({}, config); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } + tempConfig._f = config._f[i]; + configFromStringAndFormat(tempConfig); + + if (!valid__isValid(tempConfig)) { + continue; + } + + // if there is any input that was not parsed add a penalty for that format + currentScore += getParsingFlags(tempConfig).charsLeftOver; + + //or tokens + currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; + + getParsingFlags(tempConfig).score = currentScore; + + if (scoreToBeat == null || currentScore < scoreToBeat) { + scoreToBeat = currentScore; + bestMoment = tempConfig; + } + } + + extend(config, bestMoment || tempConfig); + } + + function configFromObject(config) { + if (config._d) { + return; + } + + var i = normalizeObjectUnits(config._i); + config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { + return obj && parseInt(obj, 10); + }); + + configFromArray(config); + } + + function createFromConfig (config) { + var res = new Moment(checkOverflow(prepareConfig(config))); + if (res._nextDay) { + // Adding is smart enough around DST + res.add(1, 'd'); + res._nextDay = undefined; + } + + return res; + } + + function prepareConfig (config) { + var input = config._i, + format = config._f; + + config._locale = config._locale || locale_locales__getLocale(config._l); + + if (input === null || (format === undefined && input === '')) { + return valid__createInvalid({nullInput: true}); + } + + if (typeof input === 'string') { + config._i = input = config._locale.preparse(input); + } + + if (isMoment(input)) { + return new Moment(checkOverflow(input)); + } else if (isArray(format)) { + configFromStringAndArray(config); + } else if (format) { + configFromStringAndFormat(config); + } else if (isDate(input)) { + config._d = input; + } else { + configFromInput(config); + } + + if (!valid__isValid(config)) { + config._d = null; + } + + return config; + } + + function configFromInput(config) { + var input = config._i; + if (input === undefined) { + config._d = new Date(utils_hooks__hooks.now()); + } else if (isDate(input)) { + config._d = new Date(+input); + } else if (typeof input === 'string') { + configFromString(config); + } else if (isArray(input)) { + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); + configFromArray(config); + } else if (typeof(input) === 'object') { + configFromObject(config); + } else if (typeof(input) === 'number') { + // from milliseconds + config._d = new Date(input); + } else { + utils_hooks__hooks.createFromInputFallback(config); + } + } + + function createLocalOrUTC (input, format, locale, strict, isUTC) { + var c = {}; + + if (typeof(locale) === 'boolean') { + strict = locale; + locale = undefined; + } + // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + c._isAMomentObject = true; + c._useUTC = c._isUTC = isUTC; + c._l = locale; + c._i = input; + c._f = format; + c._strict = strict; + + return createFromConfig(c); + } + + function local__createLocal (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, false); + } + + var prototypeMin = deprecate( + 'moment().min is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548', + function () { + var other = local__createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other < this ? this : other; + } else { + return valid__createInvalid(); + } + } + ); + + var prototypeMax = deprecate( + 'moment().max is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548', + function () { + var other = local__createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other > this ? this : other; + } else { + return valid__createInvalid(); + } + } + ); + + // Pick a moment m from moments so that m[fn](other) is true for all + // other. This relies on the function fn to be transitive. + // + // moments should either be an array of moment objects or an array, whose + // first element is an array of moment objects. + function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return local__createLocal(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (!moments[i].isValid() || moments[i][fn](res)) { + res = moments[i]; + } + } + return res; + } + + // TODO: Use [].sort instead? + function min () { + var args = [].slice.call(arguments, 0); + + return pickBy('isBefore', args); + } + + function max () { + var args = [].slice.call(arguments, 0); + + return pickBy('isAfter', args); + } + + var now = function () { + return Date.now ? Date.now() : +(new Date()); + }; + + function Duration (duration) { + var normalizedInput = normalizeObjectUnits(duration), + years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, + months = normalizedInput.month || 0, + weeks = normalizedInput.week || 0, + days = normalizedInput.day || 0, + hours = normalizedInput.hour || 0, + minutes = normalizedInput.minute || 0, + seconds = normalizedInput.second || 0, + milliseconds = normalizedInput.millisecond || 0; + + // representation for dateAddRemove + this._milliseconds = +milliseconds + + seconds * 1e3 + // 1000 + minutes * 6e4 + // 1000 * 60 + hours * 36e5; // 1000 * 60 * 60 + // Because of dateAddRemove treats 24 hours as different from a + // day when working around DST, we need to store them separately + this._days = +days + + weeks * 7; + // It is impossible translate months into days without knowing + // which months you are are talking about, so we have to store + // it separately. + this._months = +months + + quarters * 3 + + years * 12; + + this._data = {}; + + this._locale = locale_locales__getLocale(); + + this._bubble(); + } + + function isDuration (obj) { + return obj instanceof Duration; + } + + // FORMATTING + + function offset (token, separator) { + addFormatToken(token, 0, 0, function () { + var offset = this.utcOffset(); + var sign = '+'; + if (offset < 0) { + offset = -offset; + sign = '-'; + } + return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); + }); + } + + offset('Z', ':'); + offset('ZZ', ''); + + // PARSING + + addRegexToken('Z', matchShortOffset); + addRegexToken('ZZ', matchShortOffset); + addParseToken(['Z', 'ZZ'], function (input, array, config) { + config._useUTC = true; + config._tzm = offsetFromString(matchShortOffset, input); + }); + + // HELPERS + + // timezone chunker + // '+10:00' > ['10', '00'] + // '-1530' > ['-15', '30'] + var chunkOffset = /([\+\-]|\d\d)/gi; + + function offsetFromString(matcher, string) { + var matches = ((string || '').match(matcher) || []); + var chunk = matches[matches.length - 1] || []; + var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; + var minutes = +(parts[1] * 60) + toInt(parts[2]); + + return parts[0] === '+' ? minutes : -minutes; + } + + // Return a moment from input, that is local/utc/zone equivalent to model. + function cloneWithOffset(input, model) { + var res, diff; + if (model._isUTC) { + res = model.clone(); + diff = (isMoment(input) || isDate(input) ? +input : +local__createLocal(input)) - (+res); + // Use low-level api, because this fn is low-level api. + res._d.setTime(+res._d + diff); + utils_hooks__hooks.updateOffset(res, false); + return res; + } else { + return local__createLocal(input).local(); + } + } + + function getDateOffset (m) { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return -Math.round(m._d.getTimezoneOffset() / 15) * 15; + } + + // HOOKS + + // This function will be called whenever a moment is mutated. + // It is intended to keep the offset in sync with the timezone. + utils_hooks__hooks.updateOffset = function () {}; + + // MOMENTS + + // keepLocalTime = true means only change the timezone, without + // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> + // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset + // +0200, so we adjust the time as needed, to be valid. + // + // Keeping the time actually adds/subtracts (one hour) + // from the actual represented time. That is why we call updateOffset + // a second time. In case it wants us to change the offset again + // _changeInProgress == true case, then we have to adjust, because + // there is no such time in the given timezone. + function getSetOffset (input, keepLocalTime) { + var offset = this._offset || 0, + localAdjust; + if (!this.isValid()) { + return input != null ? this : NaN; + } + if (input != null) { + if (typeof input === 'string') { + input = offsetFromString(matchShortOffset, input); + } else if (Math.abs(input) < 16) { + input = input * 60; + } + if (!this._isUTC && keepLocalTime) { + localAdjust = getDateOffset(this); + } + this._offset = input; + this._isUTC = true; + if (localAdjust != null) { + this.add(localAdjust, 'm'); + } + if (offset !== input) { + if (!keepLocalTime || this._changeInProgress) { + add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + utils_hooks__hooks.updateOffset(this, true); + this._changeInProgress = null; + } + } + return this; + } else { + return this._isUTC ? offset : getDateOffset(this); + } + } + + function getSetZone (input, keepLocalTime) { + if (input != null) { + if (typeof input !== 'string') { + input = -input; + } + + this.utcOffset(input, keepLocalTime); + + return this; + } else { + return -this.utcOffset(); + } + } + + function setOffsetToUTC (keepLocalTime) { + return this.utcOffset(0, keepLocalTime); + } + + function setOffsetToLocal (keepLocalTime) { + if (this._isUTC) { + this.utcOffset(0, keepLocalTime); + this._isUTC = false; + + if (keepLocalTime) { + this.subtract(getDateOffset(this), 'm'); + } + } + return this; + } + + function setOffsetToParsedOffset () { + if (this._tzm) { + this.utcOffset(this._tzm); + } else if (typeof this._i === 'string') { + this.utcOffset(offsetFromString(matchOffset, this._i)); + } + return this; + } + + function hasAlignedHourOffset (input) { + if (!this.isValid()) { + return false; + } + input = input ? local__createLocal(input).utcOffset() : 0; + + return (this.utcOffset() - input) % 60 === 0; + } + + function isDaylightSavingTime () { + return ( + this.utcOffset() > this.clone().month(0).utcOffset() || + this.utcOffset() > this.clone().month(5).utcOffset() + ); + } + + function isDaylightSavingTimeShifted () { + if (!isUndefined(this._isDSTShifted)) { + return this._isDSTShifted; + } + + var c = {}; + + copyConfig(c, this); + c = prepareConfig(c); + + if (c._a) { + var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a); + this._isDSTShifted = this.isValid() && + compareArrays(c._a, other.toArray()) > 0; + } else { + this._isDSTShifted = false; + } + + return this._isDSTShifted; + } + + function isLocal () { + return this.isValid() ? !this._isUTC : false; + } + + function isUtcOffset () { + return this.isValid() ? this._isUTC : false; + } + + function isUtc () { + return this.isValid() ? this._isUTC && this._offset === 0 : false; + } + + // ASP.NET json date format regex + var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/; + + // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html + // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere + // and further modified to allow for strings containing both week and day + var isoRegex = /^(-)?P(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)W)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?$/; + + function create__createDuration (input, key) { + var duration = input, + // matching against regexp is expensive, do it on demand + match = null, + sign, + ret, + diffRes; + + if (isDuration(input)) { + duration = { + ms : input._milliseconds, + d : input._days, + M : input._months + }; + } else if (typeof input === 'number') { + duration = {}; + if (key) { + duration[key] = input; + } else { + duration.milliseconds = input; + } + } else if (!!(match = aspNetRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + duration = { + y : 0, + d : toInt(match[DATE]) * sign, + h : toInt(match[HOUR]) * sign, + m : toInt(match[MINUTE]) * sign, + s : toInt(match[SECOND]) * sign, + ms : toInt(match[MILLISECOND]) * sign + }; + } else if (!!(match = isoRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + duration = { + y : parseIso(match[2], sign), + M : parseIso(match[3], sign), + w : parseIso(match[4], sign), + d : parseIso(match[5], sign), + h : parseIso(match[6], sign), + m : parseIso(match[7], sign), + s : parseIso(match[8], sign) + }; + } else if (duration == null) {// checks for null or undefined + duration = {}; + } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to)); + + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; + } + + ret = new Duration(duration); + + if (isDuration(input) && hasOwnProp(input, '_locale')) { + ret._locale = input._locale; + } + + return ret; + } + + create__createDuration.fn = Duration.prototype; + + function parseIso (inp, sign) { + // We'd normally use ~~inp for this, but unfortunately it also + // converts floats to ints. + // inp may be undefined, so careful calling replace on it. + var res = inp && parseFloat(inp.replace(',', '.')); + // apply sign while we're at it + return (isNaN(res) ? 0 : res) * sign; + } + + function positiveMomentsDifference(base, other) { + var res = {milliseconds: 0, months: 0}; + + res.months = other.month() - base.month() + + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } + + res.milliseconds = +other - +(base.clone().add(res.months, 'M')); + + return res; + } + + function momentsDifference(base, other) { + var res; + if (!(base.isValid() && other.isValid())) { + return {milliseconds: 0, months: 0}; + } + + other = cloneWithOffset(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } + + return res; + } + + function absRound (number) { + if (number < 0) { + return Math.round(-1 * number) * -1; + } else { + return Math.round(number); + } + } + + // TODO: remove 'name' arg after deprecation is removed + function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).'); + tmp = val; val = period; period = tmp; + } + + val = typeof val === 'string' ? +val : val; + dur = create__createDuration(val, period); + add_subtract__addSubtract(this, dur, direction); + return this; + }; + } + + function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) { + var milliseconds = duration._milliseconds, + days = absRound(duration._days), + months = absRound(duration._months); + + if (!mom.isValid()) { + // No op + return; + } + + updateOffset = updateOffset == null ? true : updateOffset; + + if (milliseconds) { + mom._d.setTime(+mom._d + milliseconds * isAdding); + } + if (days) { + get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding); + } + if (months) { + setMonth(mom, get_set__get(mom, 'Month') + months * isAdding); + } + if (updateOffset) { + utils_hooks__hooks.updateOffset(mom, days || months); + } + } + + var add_subtract__add = createAdder(1, 'add'); + var add_subtract__subtract = createAdder(-1, 'subtract'); + + function moment_calendar__calendar (time, formats) { + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're local/utc/offset or not. + var now = time || local__createLocal(), + sod = cloneWithOffset(now, this).startOf('day'), + diff = this.diff(sod, 'days', true), + format = diff < -6 ? 'sameElse' : + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : 'sameElse'; + + var output = formats && (isFunction(formats[format]) ? formats[format]() : formats[format]); + + return this.format(output || this.localeData().calendar(format, this, local__createLocal(now))); + } + + function clone () { + return new Moment(this); + } + + function isAfter (input, units) { + var localInput = isMoment(input) ? input : local__createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + if (units === 'millisecond') { + return +this > +localInput; + } else { + return +localInput < +this.clone().startOf(units); + } + } + + function isBefore (input, units) { + var localInput = isMoment(input) ? input : local__createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + if (units === 'millisecond') { + return +this < +localInput; + } else { + return +this.clone().endOf(units) < +localInput; + } + } + + function isBetween (from, to, units) { + return this.isAfter(from, units) && this.isBefore(to, units); + } + + function isSame (input, units) { + var localInput = isMoment(input) ? input : local__createLocal(input), + inputMs; + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units || 'millisecond'); + if (units === 'millisecond') { + return +this === +localInput; + } else { + inputMs = +localInput; + return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units)); + } + } + + function isSameOrAfter (input, units) { + return this.isSame(input, units) || this.isAfter(input,units); + } + + function isSameOrBefore (input, units) { + return this.isSame(input, units) || this.isBefore(input,units); + } + + function diff (input, units, asFloat) { + var that, + zoneDelta, + delta, output; + + if (!this.isValid()) { + return NaN; + } + + that = cloneWithOffset(input, this); + + if (!that.isValid()) { + return NaN; + } + + zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; + + units = normalizeUnits(units); + + if (units === 'year' || units === 'month' || units === 'quarter') { + output = monthDiff(this, that); + if (units === 'quarter') { + output = output / 3; + } else if (units === 'year') { + output = output / 12; + } + } else { + delta = this - that; + output = units === 'second' ? delta / 1e3 : // 1000 + units === 'minute' ? delta / 6e4 : // 1000 * 60 + units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60 + units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst + units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst + delta; + } + return asFloat ? output : absFloor(output); + } + + function monthDiff (a, b) { + // difference in months + var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), + // b is in (anchor - 1 month, anchor + 1 month) + anchor = a.clone().add(wholeMonthDiff, 'months'), + anchor2, adjust; + + if (b - anchor < 0) { + anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor - anchor2); + } else { + anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor2 - anchor); + } + + return -(wholeMonthDiff + adjust); + } + + utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; + + function toString () { + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); + } + + function moment_format__toISOString () { + var m = this.clone().utc(); + if (0 < m.year() && m.year() <= 9999) { + if (isFunction(Date.prototype.toISOString)) { + // native implementation is ~50x faster, use it when we can + return this.toDate().toISOString(); + } else { + return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + } + } else { + return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + } + } + + function moment_format__format (inputString) { + var output = formatMoment(this, inputString || utils_hooks__hooks.defaultFormat); + return this.localeData().postformat(output); + } + + function from (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + local__createLocal(time).isValid())) { + return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } + + function fromNow (withoutSuffix) { + return this.from(local__createLocal(), withoutSuffix); + } + + function to (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + local__createLocal(time).isValid())) { + return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } + } + + function toNow (withoutSuffix) { + return this.to(local__createLocal(), withoutSuffix); + } + + // If passed a locale key, it will set the locale for this + // instance. Otherwise, it will return the locale configuration + // variables for this instance. + function locale (key) { + var newLocaleData; + + if (key === undefined) { + return this._locale._abbr; + } else { + newLocaleData = locale_locales__getLocale(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } + return this; + } + } + + var lang = deprecate( + 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } + } + ); + + function localeData () { + return this._locale; + } + + function startOf (units) { + units = normalizeUnits(units); + // the following switch intentionally omits break keywords + // to utilize falling through the cases. + switch (units) { + case 'year': + this.month(0); + /* falls through */ + case 'quarter': + case 'month': + this.date(1); + /* falls through */ + case 'week': + case 'isoWeek': + case 'day': + this.hours(0); + /* falls through */ + case 'hour': + this.minutes(0); + /* falls through */ + case 'minute': + this.seconds(0); + /* falls through */ + case 'second': + this.milliseconds(0); + } + + // weeks are a special case + if (units === 'week') { + this.weekday(0); + } + if (units === 'isoWeek') { + this.isoWeekday(1); + } + + // quarters are also special + if (units === 'quarter') { + this.month(Math.floor(this.month() / 3) * 3); + } + + return this; + } + + function endOf (units) { + units = normalizeUnits(units); + if (units === undefined || units === 'millisecond') { + return this; + } + return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); + } + + function to_type__valueOf () { + return +this._d - ((this._offset || 0) * 60000); + } + + function unix () { + return Math.floor(+this / 1000); + } + + function toDate () { + return this._offset ? new Date(+this) : this._d; + } + + function toArray () { + var m = this; + return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; + } + + function toObject () { + var m = this; + return { + years: m.year(), + months: m.month(), + date: m.date(), + hours: m.hours(), + minutes: m.minutes(), + seconds: m.seconds(), + milliseconds: m.milliseconds() + }; + } + + function toJSON () { + // new Date(NaN).toJSON() === null + return this.isValid() ? this.toISOString() : null; + } + + function moment_valid__isValid () { + return valid__isValid(this); + } + + function parsingFlags () { + return extend({}, getParsingFlags(this)); + } + + function invalidAt () { + return getParsingFlags(this).overflow; + } + + function creationData() { + return { + input: this._i, + format: this._f, + locale: this._locale, + isUTC: this._isUTC, + strict: this._strict + }; + } + + // FORMATTING + + addFormatToken(0, ['gg', 2], 0, function () { + return this.weekYear() % 100; + }); + + addFormatToken(0, ['GG', 2], 0, function () { + return this.isoWeekYear() % 100; + }); + + function addWeekYearFormatToken (token, getter) { + addFormatToken(0, [token, token.length], 0, getter); + } + + addWeekYearFormatToken('gggg', 'weekYear'); + addWeekYearFormatToken('ggggg', 'weekYear'); + addWeekYearFormatToken('GGGG', 'isoWeekYear'); + addWeekYearFormatToken('GGGGG', 'isoWeekYear'); + + // ALIASES + + addUnitAlias('weekYear', 'gg'); + addUnitAlias('isoWeekYear', 'GG'); + + // PARSING + + addRegexToken('G', matchSigned); + addRegexToken('g', matchSigned); + addRegexToken('GG', match1to2, match2); + addRegexToken('gg', match1to2, match2); + addRegexToken('GGGG', match1to4, match4); + addRegexToken('gggg', match1to4, match4); + addRegexToken('GGGGG', match1to6, match6); + addRegexToken('ggggg', match1to6, match6); + + addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { + week[token.substr(0, 2)] = toInt(input); + }); + + addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { + week[token] = utils_hooks__hooks.parseTwoDigitYear(input); + }); + + // MOMENTS + + function getSetWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, + this.week(), + this.weekday(), + this.localeData()._week.dow, + this.localeData()._week.doy); + } + + function getSetISOWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, this.isoWeek(), this.isoWeekday(), 1, 4); + } + + function getISOWeeksInYear () { + return weeksInYear(this.year(), 1, 4); + } + + function getWeeksInYear () { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); + } + + function getSetWeekYearHelper(input, week, weekday, dow, doy) { + var weeksTarget; + if (input == null) { + return weekOfYear(this, dow, doy).year; + } else { + weeksTarget = weeksInYear(input, dow, doy); + if (week > weeksTarget) { + week = weeksTarget; + } + return setWeekAll.call(this, input, week, weekday, dow, doy); + } + } + + function setWeekAll(weekYear, week, weekday, dow, doy) { + var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), + date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); + + this.year(date.getUTCFullYear()); + this.month(date.getUTCMonth()); + this.date(date.getUTCDate()); + return this; + } + + // FORMATTING + + addFormatToken('Q', 0, 'Qo', 'quarter'); + + // ALIASES + + addUnitAlias('quarter', 'Q'); + + // PARSING + + addRegexToken('Q', match1); + addParseToken('Q', function (input, array) { + array[MONTH] = (toInt(input) - 1) * 3; + }); + + // MOMENTS + + function getSetQuarter (input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); + } + + // FORMATTING + + addFormatToken('w', ['ww', 2], 'wo', 'week'); + addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); + + // ALIASES + + addUnitAlias('week', 'w'); + addUnitAlias('isoWeek', 'W'); + + // PARSING + + addRegexToken('w', match1to2); + addRegexToken('ww', match1to2, match2); + addRegexToken('W', match1to2); + addRegexToken('WW', match1to2, match2); + + addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { + week[token.substr(0, 1)] = toInt(input); + }); + + // HELPERS + + // LOCALES + + function localeWeek (mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; + } + + var defaultLocaleWeek = { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + }; + + function localeFirstDayOfWeek () { + return this._week.dow; + } + + function localeFirstDayOfYear () { + return this._week.doy; + } + + // MOMENTS + + function getSetWeek (input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + function getSetISOWeek (input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + // FORMATTING + + addFormatToken('D', ['DD', 2], 'Do', 'date'); + + // ALIASES + + addUnitAlias('date', 'D'); + + // PARSING + + addRegexToken('D', match1to2); + addRegexToken('DD', match1to2, match2); + addRegexToken('Do', function (isStrict, locale) { + return isStrict ? locale._ordinalParse : locale._ordinalParseLenient; + }); + + addParseToken(['D', 'DD'], DATE); + addParseToken('Do', function (input, array) { + array[DATE] = toInt(input.match(match1to2)[0], 10); + }); + + // MOMENTS + + var getSetDayOfMonth = makeGetSet('Date', true); + + // FORMATTING + + addFormatToken('d', 0, 'do', 'day'); + + addFormatToken('dd', 0, 0, function (format) { + return this.localeData().weekdaysMin(this, format); + }); + + addFormatToken('ddd', 0, 0, function (format) { + return this.localeData().weekdaysShort(this, format); + }); + + addFormatToken('dddd', 0, 0, function (format) { + return this.localeData().weekdays(this, format); + }); + + addFormatToken('e', 0, 0, 'weekday'); + addFormatToken('E', 0, 0, 'isoWeekday'); + + // ALIASES + + addUnitAlias('day', 'd'); + addUnitAlias('weekday', 'e'); + addUnitAlias('isoWeekday', 'E'); + + // PARSING + + addRegexToken('d', match1to2); + addRegexToken('e', match1to2); + addRegexToken('E', match1to2); + addRegexToken('dd', matchWord); + addRegexToken('ddd', matchWord); + addRegexToken('dddd', matchWord); + + addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { + var weekday = config._locale.weekdaysParse(input, token, config._strict); + // if we didn't get a weekday name, mark the date as invalid + if (weekday != null) { + week.d = weekday; + } else { + getParsingFlags(config).invalidWeekday = input; + } + }); + + addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { + week[token] = toInt(input); + }); + + // HELPERS + + function parseWeekday(input, locale) { + if (typeof input !== 'string') { + return input; + } + + if (!isNaN(input)) { + return parseInt(input, 10); + } + + input = locale.weekdaysParse(input); + if (typeof input === 'number') { + return input; + } + + return null; + } + + // LOCALES + + var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); + function localeWeekdays (m, format) { + return isArray(this._weekdays) ? this._weekdays[m.day()] : + this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()]; + } + + var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); + function localeWeekdaysShort (m) { + return this._weekdaysShort[m.day()]; + } + + var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); + function localeWeekdaysMin (m) { + return this._weekdaysMin[m.day()]; + } + + function localeWeekdaysParse (weekdayName, format, strict) { + var i, mom, regex; + + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._minWeekdaysParse = []; + this._shortWeekdaysParse = []; + this._fullWeekdaysParse = []; + } + + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + + mom = local__createLocal([2000, 1]).day(i); + if (strict && !this._fullWeekdaysParse[i]) { + this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i'); + this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i'); + this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i'); + } + if (!this._weekdaysParse[i]) { + regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); + this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { + return i; + } + } + } + + // MOMENTS + + function getSetDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); + if (input != null) { + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); + } else { + return day; + } + } + + function getSetLocaleDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); + } + + function getSetISODayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + // behaves the same as moment#day except + // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) + // as a setter, sunday should belong to the previous week. + return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); + } + + // FORMATTING + + addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); + + // ALIASES + + addUnitAlias('dayOfYear', 'DDD'); + + // PARSING + + addRegexToken('DDD', match1to3); + addRegexToken('DDDD', match3); + addParseToken(['DDD', 'DDDD'], function (input, array, config) { + config._dayOfYear = toInt(input); + }); + + // HELPERS + + // MOMENTS + + function getSetDayOfYear (input) { + var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); + } + + // FORMATTING + + function hFormat() { + return this.hours() % 12 || 12; + } + + addFormatToken('H', ['HH', 2], 0, 'hour'); + addFormatToken('h', ['hh', 2], 0, hFormat); + + addFormatToken('hmm', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); + }); + + addFormatToken('hmmss', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); + }); + + addFormatToken('Hmm', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2); + }); + + addFormatToken('Hmmss', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); + }); + + function meridiem (token, lowercase) { + addFormatToken(token, 0, 0, function () { + return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); + }); + } + + meridiem('a', true); + meridiem('A', false); + + // ALIASES + + addUnitAlias('hour', 'h'); + + // PARSING + + function matchMeridiem (isStrict, locale) { + return locale._meridiemParse; + } + + addRegexToken('a', matchMeridiem); + addRegexToken('A', matchMeridiem); + addRegexToken('H', match1to2); + addRegexToken('h', match1to2); + addRegexToken('HH', match1to2, match2); + addRegexToken('hh', match1to2, match2); + + addRegexToken('hmm', match3to4); + addRegexToken('hmmss', match5to6); + addRegexToken('Hmm', match3to4); + addRegexToken('Hmmss', match5to6); + + addParseToken(['H', 'HH'], HOUR); + addParseToken(['a', 'A'], function (input, array, config) { + config._isPm = config._locale.isPM(input); + config._meridiem = input; + }); + addParseToken(['h', 'hh'], function (input, array, config) { + array[HOUR] = toInt(input); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('Hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + }); + addParseToken('Hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + }); + + // LOCALES + + function localeIsPM (input) { + // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays + // Using charAt should be more compatible. + return ((input + '').toLowerCase().charAt(0) === 'p'); + } + + var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; + function localeMeridiem (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'pm' : 'PM'; + } else { + return isLower ? 'am' : 'AM'; + } + } + + + // MOMENTS + + // Setting the hour should keep the time, because the user explicitly + // specified which hour he wants. So trying to maintain the same hour (in + // a new timezone) makes sense. Adding/subtracting hours does not follow + // this rule. + var getSetHour = makeGetSet('Hours', true); + + // FORMATTING + + addFormatToken('m', ['mm', 2], 0, 'minute'); + + // ALIASES + + addUnitAlias('minute', 'm'); + + // PARSING + + addRegexToken('m', match1to2); + addRegexToken('mm', match1to2, match2); + addParseToken(['m', 'mm'], MINUTE); + + // MOMENTS + + var getSetMinute = makeGetSet('Minutes', false); + + // FORMATTING + + addFormatToken('s', ['ss', 2], 0, 'second'); + + // ALIASES + + addUnitAlias('second', 's'); + + // PARSING + + addRegexToken('s', match1to2); + addRegexToken('ss', match1to2, match2); + addParseToken(['s', 'ss'], SECOND); + + // MOMENTS + + var getSetSecond = makeGetSet('Seconds', false); + + // FORMATTING + + addFormatToken('S', 0, 0, function () { + return ~~(this.millisecond() / 100); + }); + + addFormatToken(0, ['SS', 2], 0, function () { + return ~~(this.millisecond() / 10); + }); + + addFormatToken(0, ['SSS', 3], 0, 'millisecond'); + addFormatToken(0, ['SSSS', 4], 0, function () { + return this.millisecond() * 10; + }); + addFormatToken(0, ['SSSSS', 5], 0, function () { + return this.millisecond() * 100; + }); + addFormatToken(0, ['SSSSSS', 6], 0, function () { + return this.millisecond() * 1000; + }); + addFormatToken(0, ['SSSSSSS', 7], 0, function () { + return this.millisecond() * 10000; + }); + addFormatToken(0, ['SSSSSSSS', 8], 0, function () { + return this.millisecond() * 100000; + }); + addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { + return this.millisecond() * 1000000; + }); + + + // ALIASES + + addUnitAlias('millisecond', 'ms'); + + // PARSING + + addRegexToken('S', match1to3, match1); + addRegexToken('SS', match1to3, match2); + addRegexToken('SSS', match1to3, match3); + + var token; + for (token = 'SSSS'; token.length <= 9; token += 'S') { + addRegexToken(token, matchUnsigned); + } + + function parseMs(input, array) { + array[MILLISECOND] = toInt(('0.' + input) * 1000); + } + + for (token = 'S'; token.length <= 9; token += 'S') { + addParseToken(token, parseMs); + } + // MOMENTS + + var getSetMillisecond = makeGetSet('Milliseconds', false); + + // FORMATTING + + addFormatToken('z', 0, 0, 'zoneAbbr'); + addFormatToken('zz', 0, 0, 'zoneName'); + + // MOMENTS + + function getZoneAbbr () { + return this._isUTC ? 'UTC' : ''; + } + + function getZoneName () { + return this._isUTC ? 'Coordinated Universal Time' : ''; + } + + var momentPrototype__proto = Moment.prototype; + + momentPrototype__proto.add = add_subtract__add; + momentPrototype__proto.calendar = moment_calendar__calendar; + momentPrototype__proto.clone = clone; + momentPrototype__proto.diff = diff; + momentPrototype__proto.endOf = endOf; + momentPrototype__proto.format = moment_format__format; + momentPrototype__proto.from = from; + momentPrototype__proto.fromNow = fromNow; + momentPrototype__proto.to = to; + momentPrototype__proto.toNow = toNow; + momentPrototype__proto.get = getSet; + momentPrototype__proto.invalidAt = invalidAt; + momentPrototype__proto.isAfter = isAfter; + momentPrototype__proto.isBefore = isBefore; + momentPrototype__proto.isBetween = isBetween; + momentPrototype__proto.isSame = isSame; + momentPrototype__proto.isSameOrAfter = isSameOrAfter; + momentPrototype__proto.isSameOrBefore = isSameOrBefore; + momentPrototype__proto.isValid = moment_valid__isValid; + momentPrototype__proto.lang = lang; + momentPrototype__proto.locale = locale; + momentPrototype__proto.localeData = localeData; + momentPrototype__proto.max = prototypeMax; + momentPrototype__proto.min = prototypeMin; + momentPrototype__proto.parsingFlags = parsingFlags; + momentPrototype__proto.set = getSet; + momentPrototype__proto.startOf = startOf; + momentPrototype__proto.subtract = add_subtract__subtract; + momentPrototype__proto.toArray = toArray; + momentPrototype__proto.toObject = toObject; + momentPrototype__proto.toDate = toDate; + momentPrototype__proto.toISOString = moment_format__toISOString; + momentPrototype__proto.toJSON = toJSON; + momentPrototype__proto.toString = toString; + momentPrototype__proto.unix = unix; + momentPrototype__proto.valueOf = to_type__valueOf; + momentPrototype__proto.creationData = creationData; + + // Year + momentPrototype__proto.year = getSetYear; + momentPrototype__proto.isLeapYear = getIsLeapYear; + + // Week Year + momentPrototype__proto.weekYear = getSetWeekYear; + momentPrototype__proto.isoWeekYear = getSetISOWeekYear; + + // Quarter + momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter; + + // Month + momentPrototype__proto.month = getSetMonth; + momentPrototype__proto.daysInMonth = getDaysInMonth; + + // Week + momentPrototype__proto.week = momentPrototype__proto.weeks = getSetWeek; + momentPrototype__proto.isoWeek = momentPrototype__proto.isoWeeks = getSetISOWeek; + momentPrototype__proto.weeksInYear = getWeeksInYear; + momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear; + + // Day + momentPrototype__proto.date = getSetDayOfMonth; + momentPrototype__proto.day = momentPrototype__proto.days = getSetDayOfWeek; + momentPrototype__proto.weekday = getSetLocaleDayOfWeek; + momentPrototype__proto.isoWeekday = getSetISODayOfWeek; + momentPrototype__proto.dayOfYear = getSetDayOfYear; + + // Hour + momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour; + + // Minute + momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute; + + // Second + momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond; + + // Millisecond + momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond; + + // Offset + momentPrototype__proto.utcOffset = getSetOffset; + momentPrototype__proto.utc = setOffsetToUTC; + momentPrototype__proto.local = setOffsetToLocal; + momentPrototype__proto.parseZone = setOffsetToParsedOffset; + momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset; + momentPrototype__proto.isDST = isDaylightSavingTime; + momentPrototype__proto.isDSTShifted = isDaylightSavingTimeShifted; + momentPrototype__proto.isLocal = isLocal; + momentPrototype__proto.isUtcOffset = isUtcOffset; + momentPrototype__proto.isUtc = isUtc; + momentPrototype__proto.isUTC = isUtc; + + // Timezone + momentPrototype__proto.zoneAbbr = getZoneAbbr; + momentPrototype__proto.zoneName = getZoneName; + + // Deprecations + momentPrototype__proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); + momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); + momentPrototype__proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); + momentPrototype__proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779', getSetZone); + + var momentPrototype = momentPrototype__proto; + + function moment_moment__createUnix (input) { + return local__createLocal(input * 1000); + } + + function moment_moment__createInZone () { + return local__createLocal.apply(null, arguments).parseZone(); + } + + var defaultCalendar = { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }; + + function locale_calendar__calendar (key, mom, now) { + var output = this._calendar[key]; + return isFunction(output) ? output.call(mom, now) : output; + } + + var defaultLongDateFormat = { + LTS : 'h:mm:ss A', + LT : 'h:mm A', + L : 'MM/DD/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY h:mm A', + LLLL : 'dddd, MMMM D, YYYY h:mm A' + }; + + function longDateFormat (key) { + var format = this._longDateFormat[key], + formatUpper = this._longDateFormat[key.toUpperCase()]; + + if (format || !formatUpper) { + return format; + } + + this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { + return val.slice(1); + }); + + return this._longDateFormat[key]; + } + + var defaultInvalidDate = 'Invalid date'; + + function invalidDate () { + return this._invalidDate; + } + + var defaultOrdinal = '%d'; + var defaultOrdinalParse = /\d{1,2}/; + + function ordinal (number) { + return this._ordinal.replace('%d', number); + } + + function preParsePostFormat (string) { + return string; + } + + var defaultRelativeTime = { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }; + + function relative__relativeTime (number, withoutSuffix, string, isFuture) { + var output = this._relativeTime[string]; + return (isFunction(output)) ? + output(number, withoutSuffix, string, isFuture) : + output.replace(/%d/i, number); + } + + function pastFuture (diff, output) { + var format = this._relativeTime[diff > 0 ? 'future' : 'past']; + return isFunction(format) ? format(output) : format.replace(/%s/i, output); + } + + var prototype__proto = Locale.prototype; + + prototype__proto._calendar = defaultCalendar; + prototype__proto.calendar = locale_calendar__calendar; + prototype__proto._longDateFormat = defaultLongDateFormat; + prototype__proto.longDateFormat = longDateFormat; + prototype__proto._invalidDate = defaultInvalidDate; + prototype__proto.invalidDate = invalidDate; + prototype__proto._ordinal = defaultOrdinal; + prototype__proto.ordinal = ordinal; + prototype__proto._ordinalParse = defaultOrdinalParse; + prototype__proto.preparse = preParsePostFormat; + prototype__proto.postformat = preParsePostFormat; + prototype__proto._relativeTime = defaultRelativeTime; + prototype__proto.relativeTime = relative__relativeTime; + prototype__proto.pastFuture = pastFuture; + prototype__proto.set = locale_set__set; + + // Month + prototype__proto.months = localeMonths; + prototype__proto._months = defaultLocaleMonths; + prototype__proto.monthsShort = localeMonthsShort; + prototype__proto._monthsShort = defaultLocaleMonthsShort; + prototype__proto.monthsParse = localeMonthsParse; + prototype__proto._monthsRegex = defaultMonthsRegex; + prototype__proto.monthsRegex = monthsRegex; + prototype__proto._monthsShortRegex = defaultMonthsShortRegex; + prototype__proto.monthsShortRegex = monthsShortRegex; + + // Week + prototype__proto.week = localeWeek; + prototype__proto._week = defaultLocaleWeek; + prototype__proto.firstDayOfYear = localeFirstDayOfYear; + prototype__proto.firstDayOfWeek = localeFirstDayOfWeek; + + // Day of Week + prototype__proto.weekdays = localeWeekdays; + prototype__proto._weekdays = defaultLocaleWeekdays; + prototype__proto.weekdaysMin = localeWeekdaysMin; + prototype__proto._weekdaysMin = defaultLocaleWeekdaysMin; + prototype__proto.weekdaysShort = localeWeekdaysShort; + prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort; + prototype__proto.weekdaysParse = localeWeekdaysParse; + + // Hours + prototype__proto.isPM = localeIsPM; + prototype__proto._meridiemParse = defaultLocaleMeridiemParse; + prototype__proto.meridiem = localeMeridiem; + + function lists__get (format, index, field, setter) { + var locale = locale_locales__getLocale(); + var utc = create_utc__createUTC().set(setter, index); + return locale[field](utc, format); + } + + function list (format, index, field, count, setter) { + if (typeof format === 'number') { + index = format; + format = undefined; + } + + format = format || ''; + + if (index != null) { + return lists__get(format, index, field, setter); + } + + var i; + var out = []; + for (i = 0; i < count; i++) { + out[i] = lists__get(format, i, field, setter); + } + return out; + } + + function lists__listMonths (format, index) { + return list(format, index, 'months', 12, 'month'); + } + + function lists__listMonthsShort (format, index) { + return list(format, index, 'monthsShort', 12, 'month'); + } + + function lists__listWeekdays (format, index) { + return list(format, index, 'weekdays', 7, 'day'); + } + + function lists__listWeekdaysShort (format, index) { + return list(format, index, 'weekdaysShort', 7, 'day'); + } + + function lists__listWeekdaysMin (format, index) { + return list(format, index, 'weekdaysMin', 7, 'day'); + } + + locale_locales__getSetGlobalLocale('en', { + ordinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal : function (number) { + var b = number % 10, + output = (toInt(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } + }); + + // Side effect imports + utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale); + utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale); + + var mathAbs = Math.abs; + + function duration_abs__abs () { + var data = this._data; + + this._milliseconds = mathAbs(this._milliseconds); + this._days = mathAbs(this._days); + this._months = mathAbs(this._months); + + data.milliseconds = mathAbs(data.milliseconds); + data.seconds = mathAbs(data.seconds); + data.minutes = mathAbs(data.minutes); + data.hours = mathAbs(data.hours); + data.months = mathAbs(data.months); + data.years = mathAbs(data.years); + + return this; + } + + function duration_add_subtract__addSubtract (duration, input, value, direction) { + var other = create__createDuration(input, value); + + duration._milliseconds += direction * other._milliseconds; + duration._days += direction * other._days; + duration._months += direction * other._months; + + return duration._bubble(); + } + + // supports only 2.0-style add(1, 's') or add(duration) + function duration_add_subtract__add (input, value) { + return duration_add_subtract__addSubtract(this, input, value, 1); + } + + // supports only 2.0-style subtract(1, 's') or subtract(duration) + function duration_add_subtract__subtract (input, value) { + return duration_add_subtract__addSubtract(this, input, value, -1); + } + + function absCeil (number) { + if (number < 0) { + return Math.floor(number); + } else { + return Math.ceil(number); + } + } + + function bubble () { + var milliseconds = this._milliseconds; + var days = this._days; + var months = this._months; + var data = this._data; + var seconds, minutes, hours, years, monthsFromDays; + + // if we have a mix of positive and negative values, bubble down first + // check: https://github.com/moment/moment/issues/2166 + if (!((milliseconds >= 0 && days >= 0 && months >= 0) || + (milliseconds <= 0 && days <= 0 && months <= 0))) { + milliseconds += absCeil(monthsToDays(months) + days) * 864e5; + days = 0; + months = 0; + } + + // The following code bubbles up values, see the tests for + // examples of what that means. + data.milliseconds = milliseconds % 1000; + + seconds = absFloor(milliseconds / 1000); + data.seconds = seconds % 60; + + minutes = absFloor(seconds / 60); + data.minutes = minutes % 60; + + hours = absFloor(minutes / 60); + data.hours = hours % 24; + + days += absFloor(hours / 24); + + // convert days to months + monthsFromDays = absFloor(daysToMonths(days)); + months += monthsFromDays; + days -= absCeil(monthsToDays(monthsFromDays)); + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + data.days = days; + data.months = months; + data.years = years; + + return this; + } + + function daysToMonths (days) { + // 400 years have 146097 days (taking into account leap year rules) + // 400 years have 12 months === 4800 + return days * 4800 / 146097; + } + + function monthsToDays (months) { + // the reverse of daysToMonths + return months * 146097 / 4800; + } + + function as (units) { + var days; + var months; + var milliseconds = this._milliseconds; + + units = normalizeUnits(units); + + if (units === 'month' || units === 'year') { + days = this._days + milliseconds / 864e5; + months = this._months + daysToMonths(days); + return units === 'month' ? months : months / 12; + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + Math.round(monthsToDays(this._months)); + switch (units) { + case 'week' : return days / 7 + milliseconds / 6048e5; + case 'day' : return days + milliseconds / 864e5; + case 'hour' : return days * 24 + milliseconds / 36e5; + case 'minute' : return days * 1440 + milliseconds / 6e4; + case 'second' : return days * 86400 + milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': return Math.floor(days * 864e5) + milliseconds; + default: throw new Error('Unknown unit ' + units); + } + } + } + + // TODO: Use this.as('ms')? + function duration_as__valueOf () { + return ( + this._milliseconds + + this._days * 864e5 + + (this._months % 12) * 2592e6 + + toInt(this._months / 12) * 31536e6 + ); + } + + function makeAs (alias) { + return function () { + return this.as(alias); + }; + } + + var asMilliseconds = makeAs('ms'); + var asSeconds = makeAs('s'); + var asMinutes = makeAs('m'); + var asHours = makeAs('h'); + var asDays = makeAs('d'); + var asWeeks = makeAs('w'); + var asMonths = makeAs('M'); + var asYears = makeAs('y'); + + function duration_get__get (units) { + units = normalizeUnits(units); + return this[units + 's'](); + } + + function makeGetter(name) { + return function () { + return this._data[name]; + }; + } + + var milliseconds = makeGetter('milliseconds'); + var seconds = makeGetter('seconds'); + var minutes = makeGetter('minutes'); + var hours = makeGetter('hours'); + var days = makeGetter('days'); + var duration_get__months = makeGetter('months'); + var years = makeGetter('years'); + + function weeks () { + return absFloor(this.days() / 7); + } + + var round = Math.round; + var thresholds = { + s: 45, // seconds to minute + m: 45, // minutes to hour + h: 22, // hours to day + d: 26, // days to month + M: 11 // months to year + }; + + // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize + function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); + } + + function duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) { + var duration = create__createDuration(posNegDuration).abs(); + var seconds = round(duration.as('s')); + var minutes = round(duration.as('m')); + var hours = round(duration.as('h')); + var days = round(duration.as('d')); + var months = round(duration.as('M')); + var years = round(duration.as('y')); + + var a = seconds < thresholds.s && ['s', seconds] || + minutes <= 1 && ['m'] || + minutes < thresholds.m && ['mm', minutes] || + hours <= 1 && ['h'] || + hours < thresholds.h && ['hh', hours] || + days <= 1 && ['d'] || + days < thresholds.d && ['dd', days] || + months <= 1 && ['M'] || + months < thresholds.M && ['MM', months] || + years <= 1 && ['y'] || ['yy', years]; + + a[2] = withoutSuffix; + a[3] = +posNegDuration > 0; + a[4] = locale; + return substituteTimeAgo.apply(null, a); + } + + // This function allows you to set a threshold for relative time strings + function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) { + if (thresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return thresholds[threshold]; + } + thresholds[threshold] = limit; + return true; + } + + function humanize (withSuffix) { + var locale = this.localeData(); + var output = duration_humanize__relativeTime(this, !withSuffix, locale); + + if (withSuffix) { + output = locale.pastFuture(+this, output); + } + + return locale.postformat(output); + } + + var iso_string__abs = Math.abs; + + function iso_string__toISOString() { + // for ISO strings we do not use the normal bubbling rules: + // * milliseconds bubble up until they become hours + // * days do not bubble at all + // * months bubble up until they become years + // This is because there is no context-free conversion between hours and days + // (think of clock changes) + // and also not between days and months (28-31 days per month) + var seconds = iso_string__abs(this._milliseconds) / 1000; + var days = iso_string__abs(this._days); + var months = iso_string__abs(this._months); + var minutes, hours, years; + + // 3600 seconds -> 60 minutes -> 1 hour + minutes = absFloor(seconds / 60); + hours = absFloor(minutes / 60); + seconds %= 60; + minutes %= 60; + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + + // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js + var Y = years; + var M = months; + var D = days; + var h = hours; + var m = minutes; + var s = seconds; + var total = this.asSeconds(); + + if (!total) { + // this is the same as C#'s (Noda) and python (isodate)... + // but not other JS (goog.date) + return 'P0D'; + } + + return (total < 0 ? '-' : '') + + 'P' + + (Y ? Y + 'Y' : '') + + (M ? M + 'M' : '') + + (D ? D + 'D' : '') + + ((h || m || s) ? 'T' : '') + + (h ? h + 'H' : '') + + (m ? m + 'M' : '') + + (s ? s + 'S' : ''); + } + + var duration_prototype__proto = Duration.prototype; + + duration_prototype__proto.abs = duration_abs__abs; + duration_prototype__proto.add = duration_add_subtract__add; + duration_prototype__proto.subtract = duration_add_subtract__subtract; + duration_prototype__proto.as = as; + duration_prototype__proto.asMilliseconds = asMilliseconds; + duration_prototype__proto.asSeconds = asSeconds; + duration_prototype__proto.asMinutes = asMinutes; + duration_prototype__proto.asHours = asHours; + duration_prototype__proto.asDays = asDays; + duration_prototype__proto.asWeeks = asWeeks; + duration_prototype__proto.asMonths = asMonths; + duration_prototype__proto.asYears = asYears; + duration_prototype__proto.valueOf = duration_as__valueOf; + duration_prototype__proto._bubble = bubble; + duration_prototype__proto.get = duration_get__get; + duration_prototype__proto.milliseconds = milliseconds; + duration_prototype__proto.seconds = seconds; + duration_prototype__proto.minutes = minutes; + duration_prototype__proto.hours = hours; + duration_prototype__proto.days = days; + duration_prototype__proto.weeks = weeks; + duration_prototype__proto.months = duration_get__months; + duration_prototype__proto.years = years; + duration_prototype__proto.humanize = humanize; + duration_prototype__proto.toISOString = iso_string__toISOString; + duration_prototype__proto.toString = iso_string__toISOString; + duration_prototype__proto.toJSON = iso_string__toISOString; + duration_prototype__proto.locale = locale; + duration_prototype__proto.localeData = localeData; + + // Deprecations + duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString); + duration_prototype__proto.lang = lang; + + // Side effect imports + + // FORMATTING + + addFormatToken('X', 0, 0, 'unix'); + addFormatToken('x', 0, 0, 'valueOf'); + + // PARSING + + addRegexToken('x', matchSigned); + addRegexToken('X', matchTimestamp); + addParseToken('X', function (input, array, config) { + config._d = new Date(parseFloat(input, 10) * 1000); + }); + addParseToken('x', function (input, array, config) { + config._d = new Date(toInt(input)); + }); + + // Side effect imports + + ; + + //! moment.js + //! version : 2.12.0 + //! authors : Tim Wood, Iskren Chernev, Moment.js contributors + //! license : MIT + //! momentjs.com + + utils_hooks__hooks.version = '2.12.0'; + + setHookCallback(local__createLocal); + + utils_hooks__hooks.fn = momentPrototype; + utils_hooks__hooks.min = min; + utils_hooks__hooks.max = max; + utils_hooks__hooks.now = now; + utils_hooks__hooks.utc = create_utc__createUTC; + utils_hooks__hooks.unix = moment_moment__createUnix; + utils_hooks__hooks.months = lists__listMonths; + utils_hooks__hooks.isDate = isDate; + utils_hooks__hooks.locale = locale_locales__getSetGlobalLocale; + utils_hooks__hooks.invalid = valid__createInvalid; + utils_hooks__hooks.duration = create__createDuration; + utils_hooks__hooks.isMoment = isMoment; + utils_hooks__hooks.weekdays = lists__listWeekdays; + utils_hooks__hooks.parseZone = moment_moment__createInZone; + utils_hooks__hooks.localeData = locale_locales__getLocale; + utils_hooks__hooks.isDuration = isDuration; + utils_hooks__hooks.monthsShort = lists__listMonthsShort; + utils_hooks__hooks.weekdaysMin = lists__listWeekdaysMin; + utils_hooks__hooks.defineLocale = defineLocale; + utils_hooks__hooks.updateLocale = updateLocale; + utils_hooks__hooks.locales = locale_locales__listLocales; + utils_hooks__hooks.weekdaysShort = lists__listWeekdaysShort; + utils_hooks__hooks.normalizeUnits = normalizeUnits; + utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold; + utils_hooks__hooks.prototype = momentPrototype; + + var moment__default = utils_hooks__hooks; + + //! moment.js locale configuration + //! locale : afrikaans (af) + //! author : Werner Mollentze : https://github.com/wernerm + + var af = moment__default.defineLocale('af', { + months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'), + weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'), + weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'), + meridiemParse: /vm|nm/i, + isPM : function (input) { + return /^nm$/i.test(input); + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower ? 'vm' : 'VM'; + } else { + return isLower ? 'nm' : 'NM'; + } + }, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Vandag om] LT', + nextDay : '[Môre om] LT', + nextWeek : 'dddd [om] LT', + lastDay : '[Gister om] LT', + lastWeek : '[Laas] dddd [om] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'oor %s', + past : '%s gelede', + s : '\'n paar sekondes', + m : '\'n minuut', + mm : '%d minute', + h : '\'n uur', + hh : '%d ure', + d : '\'n dag', + dd : '%d dae', + M : '\'n maand', + MM : '%d maande', + y : '\'n jaar', + yy : '%d jaar' + }, + ordinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter + }, + week : { + dow : 1, // Maandag is die eerste dag van die week. + doy : 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar. + } + }); + + //! moment.js locale configuration + //! locale : Moroccan Arabic (ar-ma) + //! author : ElFadili Yassine : https://github.com/ElFadiliY + //! author : Abdel Said : https://github.com/abdelsaid + + var ar_ma = moment__default.defineLocale('ar-ma', { + months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), + weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Arabic Saudi Arabia (ar-sa) + //! author : Suhail Alkowaileet : https://github.com/xsoh + + var ar_sa__symbolMap = { + '1': '١', + '2': '٢', + '3': '٣', + '4': '٤', + '5': '٥', + '6': '٦', + '7': '٧', + '8': '٨', + '9': '٩', + '0': '٠' + }, ar_sa__numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0' + }; + + var ar_sa = moment__default.defineLocale('ar-sa', { + months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar : { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'في %s', + past : 'منذ %s', + s : 'ثوان', + m : 'دقيقة', + mm : '%d دقائق', + h : 'ساعة', + hh : '%d ساعات', + d : 'يوم', + dd : '%d أيام', + M : 'شهر', + MM : '%d أشهر', + y : 'سنة', + yy : '%d سنوات' + }, + preparse: function (string) { + return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { + return ar_sa__numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return ar_sa__symbolMap[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Tunisian Arabic (ar-tn) + + var ar_tn = moment__default.defineLocale('ar-tn', { + months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), + weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[اليوم على الساعة] LT', + nextDay: '[غدا على الساعة] LT', + nextWeek: 'dddd [على الساعة] LT', + lastDay: '[أمس على الساعة] LT', + lastWeek: 'dddd [على الساعة] LT', + sameElse: 'L' + }, + relativeTime: { + future: 'في %s', + past: 'منذ %s', + s: 'ثوان', + m: 'دقيقة', + mm: '%d دقائق', + h: 'ساعة', + hh: '%d ساعات', + d: 'يوم', + dd: '%d أيام', + M: 'شهر', + MM: '%d أشهر', + y: 'سنة', + yy: '%d سنوات' + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! Locale: Arabic (ar) + //! Author: Abdel Said: https://github.com/abdelsaid + //! Changes in months, weekdays: Ahmed Elkhatib + //! Native plural forms: forabi https://github.com/forabi + + var ar__symbolMap = { + '1': '١', + '2': '٢', + '3': '٣', + '4': '٤', + '5': '٥', + '6': '٦', + '7': '٧', + '8': '٨', + '9': '٩', + '0': '٠' + }, ar__numberMap = { + '١': '1', + '٢': '2', + '٣': '3', + '٤': '4', + '٥': '5', + '٦': '6', + '٧': '7', + '٨': '8', + '٩': '9', + '٠': '0' + }, pluralForm = function (n) { + return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; + }, plurals = { + s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], + m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], + h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], + d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], + M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], + y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] + }, pluralize = function (u) { + return function (number, withoutSuffix, string, isFuture) { + var f = pluralForm(number), + str = plurals[u][pluralForm(number)]; + if (f === 2) { + str = str[withoutSuffix ? 0 : 1]; + } + return str.replace(/%d/i, number); + }; + }, ar__months = [ + 'كانون الثاني يناير', + 'شباط فبراير', + 'آذار مارس', + 'نيسان أبريل', + 'أيار مايو', + 'حزيران يونيو', + 'تموز يوليو', + 'آب أغسطس', + 'أيلول سبتمبر', + 'تشرين الأول أكتوبر', + 'تشرين الثاني نوفمبر', + 'كانون الأول ديسمبر' + ]; + + var ar = moment__default.defineLocale('ar', { + months : ar__months, + monthsShort : ar__months, + weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), + weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), + weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/\u200FM/\u200FYYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ص|م/, + isPM : function (input) { + return 'م' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ص'; + } else { + return 'م'; + } + }, + calendar : { + sameDay: '[اليوم عند الساعة] LT', + nextDay: '[غدًا عند الساعة] LT', + nextWeek: 'dddd [عند الساعة] LT', + lastDay: '[أمس عند الساعة] LT', + lastWeek: 'dddd [عند الساعة] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'بعد %s', + past : 'منذ %s', + s : pluralize('s'), + m : pluralize('m'), + mm : pluralize('m'), + h : pluralize('h'), + hh : pluralize('h'), + d : pluralize('d'), + dd : pluralize('d'), + M : pluralize('M'), + MM : pluralize('M'), + y : pluralize('y'), + yy : pluralize('y') + }, + preparse: function (string) { + return string.replace(/\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { + return ar__numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return ar__symbolMap[match]; + }).replace(/,/g, '،'); + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : azerbaijani (az) + //! author : topchiyev : https://github.com/topchiyev + + var az__suffixes = { + 1: '-inci', + 5: '-inci', + 8: '-inci', + 70: '-inci', + 80: '-inci', + 2: '-nci', + 7: '-nci', + 20: '-nci', + 50: '-nci', + 3: '-üncü', + 4: '-üncü', + 100: '-üncü', + 6: '-ncı', + 9: '-uncu', + 10: '-uncu', + 30: '-uncu', + 60: '-ıncı', + 90: '-ıncı' + }; + + var az = moment__default.defineLocale('az', { + months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'), + monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'), + weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'), + weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'), + weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[bugün saat] LT', + nextDay : '[sabah saat] LT', + nextWeek : '[gələn həftə] dddd [saat] LT', + lastDay : '[dünən] LT', + lastWeek : '[keçən həftə] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s sonra', + past : '%s əvvəl', + s : 'birneçə saniyyə', + m : 'bir dəqiqə', + mm : '%d dəqiqə', + h : 'bir saat', + hh : '%d saat', + d : 'bir gün', + dd : '%d gün', + M : 'bir ay', + MM : '%d ay', + y : 'bir il', + yy : '%d il' + }, + meridiemParse: /gecə|səhər|gündüz|axşam/, + isPM : function (input) { + return /^(gündüz|axşam)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'gecə'; + } else if (hour < 12) { + return 'səhər'; + } else if (hour < 17) { + return 'gündüz'; + } else { + return 'axşam'; + } + }, + ordinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/, + ordinal : function (number) { + if (number === 0) { // special case for zero + return number + '-ıncı'; + } + var a = number % 10, + b = number % 100 - a, + c = number >= 100 ? 100 : null; + return number + (az__suffixes[a] || az__suffixes[b] || az__suffixes[c]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : belarusian (be) + //! author : Dmitry Demidov : https://github.com/demidov91 + //! author: Praleska: http://praleska.pro/ + //! Author : Menelion Elensúle : https://github.com/Oire + + function be__plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); + } + function be__relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін', + 'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін', + 'dd': 'дзень_дні_дзён', + 'MM': 'месяц_месяцы_месяцаў', + 'yy': 'год_гады_гадоў' + }; + if (key === 'm') { + return withoutSuffix ? 'хвіліна' : 'хвіліну'; + } + else if (key === 'h') { + return withoutSuffix ? 'гадзіна' : 'гадзіну'; + } + else { + return number + ' ' + be__plural(format[key], +number); + } + } + + var be = moment__default.defineLocale('be', { + months : { + format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'), + standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_') + }, + monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'), + weekdays : { + format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'), + standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'), + isFormat: /\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/ + }, + weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), + weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY г.', + LLL : 'D MMMM YYYY г., HH:mm', + LLLL : 'dddd, D MMMM YYYY г., HH:mm' + }, + calendar : { + sameDay: '[Сёння ў] LT', + nextDay: '[Заўтра ў] LT', + lastDay: '[Учора ў] LT', + nextWeek: function () { + return '[У] dddd [ў] LT'; + }, + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 5: + case 6: + return '[У мінулую] dddd [ў] LT'; + case 1: + case 2: + case 4: + return '[У мінулы] dddd [ў] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'праз %s', + past : '%s таму', + s : 'некалькі секунд', + m : be__relativeTimeWithPlural, + mm : be__relativeTimeWithPlural, + h : be__relativeTimeWithPlural, + hh : be__relativeTimeWithPlural, + d : 'дзень', + dd : be__relativeTimeWithPlural, + M : 'месяц', + MM : be__relativeTimeWithPlural, + y : 'год', + yy : be__relativeTimeWithPlural + }, + meridiemParse: /ночы|раніцы|дня|вечара/, + isPM : function (input) { + return /^(дня|вечара)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ночы'; + } else if (hour < 12) { + return 'раніцы'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечара'; + } + }, + ordinalParse: /\d{1,2}-(і|ы|га)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + case 'w': + case 'W': + return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы'; + case 'D': + return number + '-га'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : bulgarian (bg) + //! author : Krasen Borisov : https://github.com/kraz + + var bg = moment__default.defineLocale('bg', { + months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'), + monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'), + weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'), + weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'), + weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'D.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[Днес в] LT', + nextDay : '[Утре в] LT', + nextWeek : 'dddd [в] LT', + lastDay : '[Вчера в] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + case 6: + return '[В изминалата] dddd [в] LT'; + case 1: + case 2: + case 4: + case 5: + return '[В изминалия] dddd [в] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'след %s', + past : 'преди %s', + s : 'няколко секунди', + m : 'минута', + mm : '%d минути', + h : 'час', + hh : '%d часа', + d : 'ден', + dd : '%d дни', + M : 'месец', + MM : '%d месеца', + y : 'година', + yy : '%d години' + }, + ordinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, + ordinal : function (number) { + var lastDigit = number % 10, + last2Digits = number % 100; + if (number === 0) { + return number + '-ев'; + } else if (last2Digits === 0) { + return number + '-ен'; + } else if (last2Digits > 10 && last2Digits < 20) { + return number + '-ти'; + } else if (lastDigit === 1) { + return number + '-ви'; + } else if (lastDigit === 2) { + return number + '-ри'; + } else if (lastDigit === 7 || lastDigit === 8) { + return number + '-ми'; + } else { + return number + '-ти'; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Bengali (bn) + //! author : Kaushik Gandhi : https://github.com/kaushikgandhi + + var bn__symbolMap = { + '1': '১', + '2': '২', + '3': '৩', + '4': '৪', + '5': '৫', + '6': '৬', + '7': '৭', + '8': '৮', + '9': '৯', + '0': '০' + }, + bn__numberMap = { + '১': '1', + '২': '2', + '৩': '3', + '৪': '4', + '৫': '5', + '৬': '6', + '৭': '7', + '৮': '8', + '৯': '9', + '০': '0' + }; + + var bn = moment__default.defineLocale('bn', { + months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'), + monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split('_'), + weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রবার_শনিবার'.split('_'), + weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্র_শনি'.split('_'), + weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split('_'), + longDateFormat : { + LT : 'A h:mm সময়', + LTS : 'A h:mm:ss সময়', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm সময়', + LLLL : 'dddd, D MMMM YYYY, A h:mm সময়' + }, + calendar : { + sameDay : '[আজ] LT', + nextDay : '[আগামীকাল] LT', + nextWeek : 'dddd, LT', + lastDay : '[গতকাল] LT', + lastWeek : '[গত] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s পরে', + past : '%s আগে', + s : 'কয়েক সেকেন্ড', + m : 'এক মিনিট', + mm : '%d মিনিট', + h : 'এক ঘন্টা', + hh : '%d ঘন্টা', + d : 'এক দিন', + dd : '%d দিন', + M : 'এক মাস', + MM : '%d মাস', + y : 'এক বছর', + yy : '%d বছর' + }, + preparse: function (string) { + return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) { + return bn__numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return bn__symbolMap[match]; + }); + }, + meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ((meridiem === 'রাত' && hour >= 4) || + (meridiem === 'দুপুর' && hour < 5) || + meridiem === 'বিকাল') { + return hour + 12; + } else { + return hour; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'রাত'; + } else if (hour < 10) { + return 'সকাল'; + } else if (hour < 17) { + return 'দুপুর'; + } else if (hour < 20) { + return 'বিকাল'; + } else { + return 'রাত'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : tibetan (bo) + //! author : Thupten N. Chakrishar : https://github.com/vajradog + + var bo__symbolMap = { + '1': '༡', + '2': '༢', + '3': '༣', + '4': '༤', + '5': '༥', + '6': '༦', + '7': '༧', + '8': '༨', + '9': '༩', + '0': '༠' + }, + bo__numberMap = { + '༡': '1', + '༢': '2', + '༣': '3', + '༤': '4', + '༥': '5', + '༦': '6', + '༧': '7', + '༨': '8', + '༩': '9', + '༠': '0' + }; + + var bo = moment__default.defineLocale('bo', { + months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), + monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), + weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'), + weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), + weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), + longDateFormat : { + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' + }, + calendar : { + sameDay : '[དི་རིང] LT', + nextDay : '[སང་ཉིན] LT', + nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT', + lastDay : '[ཁ་སང] LT', + lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ལ་', + past : '%s སྔན་ལ', + s : 'ལམ་སང', + m : 'སྐར་མ་གཅིག', + mm : '%d སྐར་མ', + h : 'ཆུ་ཚོད་གཅིག', + hh : '%d ཆུ་ཚོད', + d : 'ཉིན་གཅིག', + dd : '%d ཉིན་', + M : 'ཟླ་བ་གཅིག', + MM : '%d ཟླ་བ', + y : 'ལོ་གཅིག', + yy : '%d ལོ' + }, + preparse: function (string) { + return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) { + return bo__numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return bo__symbolMap[match]; + }); + }, + meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ((meridiem === 'མཚན་མོ' && hour >= 4) || + (meridiem === 'ཉིན་གུང' && hour < 5) || + meridiem === 'དགོང་དག') { + return hour + 12; + } else { + return hour; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'མཚན་མོ'; + } else if (hour < 10) { + return 'ཞོགས་ཀས'; + } else if (hour < 17) { + return 'ཉིན་གུང'; + } else if (hour < 20) { + return 'དགོང་དག'; + } else { + return 'མཚན་མོ'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : breton (br) + //! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou + + function relativeTimeWithMutation(number, withoutSuffix, key) { + var format = { + 'mm': 'munutenn', + 'MM': 'miz', + 'dd': 'devezh' + }; + return number + ' ' + mutation(format[key], number); + } + function specialMutationForYears(number) { + switch (lastNumber(number)) { + case 1: + case 3: + case 4: + case 5: + case 9: + return number + ' bloaz'; + default: + return number + ' vloaz'; + } + } + function lastNumber(number) { + if (number > 9) { + return lastNumber(number % 10); + } + return number; + } + function mutation(text, number) { + if (number === 2) { + return softMutation(text); + } + return text; + } + function softMutation(text) { + var mutationTable = { + 'm': 'v', + 'b': 'v', + 'd': 'z' + }; + if (mutationTable[text.charAt(0)] === undefined) { + return text; + } + return mutationTable[text.charAt(0)] + text.substring(1); + } + + var br = moment__default.defineLocale('br', { + months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'), + monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'), + weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'), + weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'), + weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'), + longDateFormat : { + LT : 'h[e]mm A', + LTS : 'h[e]mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D [a viz] MMMM YYYY', + LLL : 'D [a viz] MMMM YYYY h[e]mm A', + LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A' + }, + calendar : { + sameDay : '[Hiziv da] LT', + nextDay : '[Warc\'hoazh da] LT', + nextWeek : 'dddd [da] LT', + lastDay : '[Dec\'h da] LT', + lastWeek : 'dddd [paset da] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'a-benn %s', + past : '%s \'zo', + s : 'un nebeud segondennoù', + m : 'ur vunutenn', + mm : relativeTimeWithMutation, + h : 'un eur', + hh : '%d eur', + d : 'un devezh', + dd : relativeTimeWithMutation, + M : 'ur miz', + MM : relativeTimeWithMutation, + y : 'ur bloaz', + yy : specialMutationForYears + }, + ordinalParse: /\d{1,2}(añ|vet)/, + ordinal : function (number) { + var output = (number === 1) ? 'añ' : 'vet'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : bosnian (bs) + //! author : Nedim Cholich : https://github.com/frontyard + //! based on (hr) translation by Bojan Marković + + function bs__translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'm': + return withoutSuffix ? 'jedna minuta' : 'jedne minute'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minuta'; + } + return result; + case 'h': + return withoutSuffix ? 'jedan sat' : 'jednog sata'; + case 'hh': + if (number === 1) { + result += 'sat'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sata'; + } else { + result += 'sati'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dana'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mjesec'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'mjeseca'; + } else { + result += 'mjeseci'; + } + return result; + case 'yy': + if (number === 1) { + result += 'godina'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'godine'; + } else { + result += 'godina'; + } + return result; + } + } + + var bs = moment__default.defineLocale('bs', { + months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'), + monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'), + weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD. MM. YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[danas u] LT', + nextDay : '[sutra u] LT', + nextWeek : function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[jučer u] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + return '[prošlu] dddd [u] LT'; + case 6: + return '[prošle] [subote] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prošli] dddd [u] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'prije %s', + s : 'par sekundi', + m : bs__translate, + mm : bs__translate, + h : bs__translate, + hh : bs__translate, + d : 'dan', + dd : bs__translate, + M : 'mjesec', + MM : bs__translate, + y : 'godinu', + yy : bs__translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : catalan (ca) + //! author : Juan G. Hurtado : https://github.com/juanghurtado + + var ca = moment__default.defineLocale('ca', { + months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'), + monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'), + weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'), + weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'), + weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd D MMMM YYYY H:mm' + }, + calendar : { + sameDay : function () { + return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + nextDay : function () { + return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + lastDay : function () { + return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'en %s', + past : 'fa %s', + s : 'uns segons', + m : 'un minut', + mm : '%d minuts', + h : 'una hora', + hh : '%d hores', + d : 'un dia', + dd : '%d dies', + M : 'un mes', + MM : '%d mesos', + y : 'un any', + yy : '%d anys' + }, + ordinalParse: /\d{1,2}(r|n|t|è|a)/, + ordinal : function (number, period) { + var output = (number === 1) ? 'r' : + (number === 2) ? 'n' : + (number === 3) ? 'r' : + (number === 4) ? 't' : 'è'; + if (period === 'w' || period === 'W') { + output = 'a'; + } + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : czech (cs) + //! author : petrbela : https://github.com/petrbela + + var cs__months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'), + cs__monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_'); + function cs__plural(n) { + return (n > 1) && (n < 5) && (~~(n / 10) !== 1); + } + function cs__translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami'; + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou'); + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (withoutSuffix || isFuture) { + return result + (cs__plural(number) ? 'minuty' : 'minut'); + } else { + return result + 'minutami'; + } + break; + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (withoutSuffix || isFuture) { + return result + (cs__plural(number) ? 'hodiny' : 'hodin'); + } else { + return result + 'hodinami'; + } + break; + case 'd': // a day / in a day / a day ago + return (withoutSuffix || isFuture) ? 'den' : 'dnem'; + case 'dd': // 9 days / in 9 days / 9 days ago + if (withoutSuffix || isFuture) { + return result + (cs__plural(number) ? 'dny' : 'dní'); + } else { + return result + 'dny'; + } + break; + case 'M': // a month / in a month / a month ago + return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem'; + case 'MM': // 9 months / in 9 months / 9 months ago + if (withoutSuffix || isFuture) { + return result + (cs__plural(number) ? 'měsíce' : 'měsíců'); + } else { + return result + 'měsíci'; + } + break; + case 'y': // a year / in a year / a year ago + return (withoutSuffix || isFuture) ? 'rok' : 'rokem'; + case 'yy': // 9 years / in 9 years / 9 years ago + if (withoutSuffix || isFuture) { + return result + (cs__plural(number) ? 'roky' : 'let'); + } else { + return result + 'lety'; + } + break; + } + } + + var cs = moment__default.defineLocale('cs', { + months : cs__months, + monthsShort : cs__monthsShort, + monthsParse : (function (months, monthsShort) { + var i, _monthsParse = []; + for (i = 0; i < 12; i++) { + // use custom parser to solve problem with July (červenec) + _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i'); + } + return _monthsParse; + }(cs__months, cs__monthsShort)), + shortMonthsParse : (function (monthsShort) { + var i, _shortMonthsParse = []; + for (i = 0; i < 12; i++) { + _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i'); + } + return _shortMonthsParse; + }(cs__monthsShort)), + longMonthsParse : (function (months) { + var i, _longMonthsParse = []; + for (i = 0; i < 12; i++) { + _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i'); + } + return _longMonthsParse; + }(cs__months)), + weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'), + weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'), + weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'), + longDateFormat : { + LT: 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd D. MMMM YYYY H:mm' + }, + calendar : { + sameDay: '[dnes v] LT', + nextDay: '[zítra v] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v neděli v] LT'; + case 1: + case 2: + return '[v] dddd [v] LT'; + case 3: + return '[ve středu v] LT'; + case 4: + return '[ve čtvrtek v] LT'; + case 5: + return '[v pátek v] LT'; + case 6: + return '[v sobotu v] LT'; + } + }, + lastDay: '[včera v] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[minulou neděli v] LT'; + case 1: + case 2: + return '[minulé] dddd [v] LT'; + case 3: + return '[minulou středu v] LT'; + case 4: + case 5: + return '[minulý] dddd [v] LT'; + case 6: + return '[minulou sobotu v] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'za %s', + past : 'před %s', + s : cs__translate, + m : cs__translate, + mm : cs__translate, + h : cs__translate, + hh : cs__translate, + d : cs__translate, + dd : cs__translate, + M : cs__translate, + MM : cs__translate, + y : cs__translate, + yy : cs__translate + }, + ordinalParse : /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : chuvash (cv) + //! author : Anatoly Mironov : https://github.com/mirontoli + + var cv = moment__default.defineLocale('cv', { + months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'), + monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'), + weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'), + weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'), + weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]', + LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm', + LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm' + }, + calendar : { + sameDay: '[Паян] LT [сехетре]', + nextDay: '[Ыран] LT [сехетре]', + lastDay: '[Ӗнер] LT [сехетре]', + nextWeek: '[Ҫитес] dddd LT [сехетре]', + lastWeek: '[Иртнӗ] dddd LT [сехетре]', + sameElse: 'L' + }, + relativeTime : { + future : function (output) { + var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран'; + return output + affix; + }, + past : '%s каялла', + s : 'пӗр-ик ҫеккунт', + m : 'пӗр минут', + mm : '%d минут', + h : 'пӗр сехет', + hh : '%d сехет', + d : 'пӗр кун', + dd : '%d кун', + M : 'пӗр уйӑх', + MM : '%d уйӑх', + y : 'пӗр ҫул', + yy : '%d ҫул' + }, + ordinalParse: /\d{1,2}-мӗш/, + ordinal : '%d-мӗш', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Welsh (cy) + //! author : Robert Allen + + var cy = moment__default.defineLocale('cy', { + months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'), + monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'), + weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'), + weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'), + weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'), + // time formats are the same as en-gb + longDateFormat: { + LT: 'HH:mm', + LTS : 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[Heddiw am] LT', + nextDay: '[Yfory am] LT', + nextWeek: 'dddd [am] LT', + lastDay: '[Ddoe am] LT', + lastWeek: 'dddd [diwethaf am] LT', + sameElse: 'L' + }, + relativeTime: { + future: 'mewn %s', + past: '%s yn ôl', + s: 'ychydig eiliadau', + m: 'munud', + mm: '%d munud', + h: 'awr', + hh: '%d awr', + d: 'diwrnod', + dd: '%d diwrnod', + M: 'mis', + MM: '%d mis', + y: 'blwyddyn', + yy: '%d flynedd' + }, + ordinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/, + // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh + ordinal: function (number) { + var b = number, + output = '', + lookup = [ + '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed + 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed + ]; + if (b > 20) { + if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) { + output = 'fed'; // not 30ain, 70ain or 90ain + } else { + output = 'ain'; + } + } else if (b > 0) { + output = lookup[b]; + } + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : danish (da) + //! author : Ulrik Nielsen : https://github.com/mrbase + + var da = moment__default.defineLocale('da', { + months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), + weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'), + weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd [d.] D. MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[I dag kl.] LT', + nextDay : '[I morgen kl.] LT', + nextWeek : 'dddd [kl.] LT', + lastDay : '[I går kl.] LT', + lastWeek : '[sidste] dddd [kl] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'om %s', + past : '%s siden', + s : 'få sekunder', + m : 'et minut', + mm : '%d minutter', + h : 'en time', + hh : '%d timer', + d : 'en dag', + dd : '%d dage', + M : 'en måned', + MM : '%d måneder', + y : 'et år', + yy : '%d år' + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : austrian german (de-at) + //! author : lluchs : https://github.com/lluchs + //! author: Menelion Elensúle: https://github.com/Oire + //! author : Martin Groller : https://github.com/MadMG + //! author : Mikolaj Dadela : https://github.com/mik01aj + + function de_at__processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + + var de_at = moment__default.defineLocale('de-at', { + months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + longDateFormat : { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' + }, + relativeTime : { + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', + m : de_at__processRelativeTime, + mm : '%d Minuten', + h : de_at__processRelativeTime, + hh : '%d Stunden', + d : de_at__processRelativeTime, + dd : de_at__processRelativeTime, + M : de_at__processRelativeTime, + MM : de_at__processRelativeTime, + y : de_at__processRelativeTime, + yy : de_at__processRelativeTime + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : german (de) + //! author : lluchs : https://github.com/lluchs + //! author: Menelion Elensúle: https://github.com/Oire + //! author : Mikolaj Dadela : https://github.com/mik01aj + + function de__processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eine Minute', 'einer Minute'], + 'h': ['eine Stunde', 'einer Stunde'], + 'd': ['ein Tag', 'einem Tag'], + 'dd': [number + ' Tage', number + ' Tagen'], + 'M': ['ein Monat', 'einem Monat'], + 'MM': [number + ' Monate', number + ' Monaten'], + 'y': ['ein Jahr', 'einem Jahr'], + 'yy': [number + ' Jahre', number + ' Jahren'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + + var de = moment__default.defineLocale('de', { + months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), + weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), + weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), + weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), + longDateFormat : { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY HH:mm', + LLLL : 'dddd, D. MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[heute um] LT [Uhr]', + sameElse: 'L', + nextDay: '[morgen um] LT [Uhr]', + nextWeek: 'dddd [um] LT [Uhr]', + lastDay: '[gestern um] LT [Uhr]', + lastWeek: '[letzten] dddd [um] LT [Uhr]' + }, + relativeTime : { + future : 'in %s', + past : 'vor %s', + s : 'ein paar Sekunden', + m : de__processRelativeTime, + mm : '%d Minuten', + h : de__processRelativeTime, + hh : '%d Stunden', + d : de__processRelativeTime, + dd : de__processRelativeTime, + M : de__processRelativeTime, + MM : de__processRelativeTime, + y : de__processRelativeTime, + yy : de__processRelativeTime + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : dhivehi (dv) + //! author : Jawish Hameed : https://github.com/jawish + + var dv__months = [ + 'ޖެނުއަރީ', + 'ފެބްރުއަރީ', + 'މާރިޗު', + 'އޭޕްރީލު', + 'މޭ', + 'ޖޫން', + 'ޖުލައި', + 'އޯގަސްޓު', + 'ސެޕްޓެމްބަރު', + 'އޮކްޓޯބަރު', + 'ނޮވެމްބަރު', + 'ޑިސެމްބަރު' + ], dv__weekdays = [ + 'އާދިއްތަ', + 'ހޯމަ', + 'އަންގާރަ', + 'ބުދަ', + 'ބުރާސްފަތި', + 'ހުކުރު', + 'ހޮނިހިރު' + ]; + + var dv = moment__default.defineLocale('dv', { + months : dv__months, + monthsShort : dv__months, + weekdays : dv__weekdays, + weekdaysShort : dv__weekdays, + weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'), + longDateFormat : { + + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'D/M/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + meridiemParse: /މކ|މފ/, + isPM : function (input) { + return 'މފ' === input; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'މކ'; + } else { + return 'މފ'; + } + }, + calendar : { + sameDay : '[މިއަދު] LT', + nextDay : '[މާދަމާ] LT', + nextWeek : 'dddd LT', + lastDay : '[އިއްޔެ] LT', + lastWeek : '[ފާއިތުވި] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ތެރޭގައި %s', + past : 'ކުރިން %s', + s : 'ސިކުންތުކޮޅެއް', + m : 'މިނިޓެއް', + mm : 'މިނިޓު %d', + h : 'ގަޑިއިރެއް', + hh : 'ގަޑިއިރު %d', + d : 'ދުވަހެއް', + dd : 'ދުވަސް %d', + M : 'މަހެއް', + MM : 'މަސް %d', + y : 'އަހަރެއް', + yy : 'އަހަރު %d' + }, + preparse: function (string) { + return string.replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/,/g, '،'); + }, + week : { + dow : 7, // Sunday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : modern greek (el) + //! author : Aggelos Karalias : https://github.com/mehiel + + var el = moment__default.defineLocale('el', { + monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'), + monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'), + months : function (momentToFormat, format) { + if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM' + return this._monthsGenitiveEl[momentToFormat.month()]; + } else { + return this._monthsNominativeEl[momentToFormat.month()]; + } + }, + monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'), + weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'), + weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'), + weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'), + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'μμ' : 'ΜΜ'; + } else { + return isLower ? 'πμ' : 'ΠΜ'; + } + }, + isPM : function (input) { + return ((input + '').toLowerCase()[0] === 'μ'); + }, + meridiemParse : /[ΠΜ]\.?Μ?\.?/i, + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendarEl : { + sameDay : '[Σήμερα {}] LT', + nextDay : '[Αύριο {}] LT', + nextWeek : 'dddd [{}] LT', + lastDay : '[Χθες {}] LT', + lastWeek : function () { + switch (this.day()) { + case 6: + return '[το προηγούμενο] dddd [{}] LT'; + default: + return '[την προηγούμενη] dddd [{}] LT'; + } + }, + sameElse : 'L' + }, + calendar : function (key, mom) { + var output = this._calendarEl[key], + hours = mom && mom.hours(); + if (isFunction(output)) { + output = output.apply(mom); + } + return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις')); + }, + relativeTime : { + future : 'σε %s', + past : '%s πριν', + s : 'λίγα δευτερόλεπτα', + m : 'ένα λεπτό', + mm : '%d λεπτά', + h : 'μία ώρα', + hh : '%d ώρες', + d : 'μία μέρα', + dd : '%d μέρες', + M : 'ένας μήνας', + MM : '%d μήνες', + y : 'ένας χρόνος', + yy : '%d χρόνια' + }, + ordinalParse: /\d{1,2}η/, + ordinal: '%dη', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : australian english (en-au) + + var en_au = moment__default.defineLocale('en-au', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + ordinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : canadian english (en-ca) + //! author : Jonathan Abourbih : https://github.com/jonbca + + var en_ca = moment__default.defineLocale('en-ca', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'YYYY-MM-DD', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY h:mm A', + LLLL : 'dddd, MMMM D, YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + ordinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } + }); + + //! moment.js locale configuration + //! locale : great britain english (en-gb) + //! author : Chris Gedrim : https://github.com/chrisgedrim + + var en_gb = moment__default.defineLocale('en-gb', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + ordinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Irish english (en-ie) + //! author : Chris Cartlidge : https://github.com/chriscartlidge + + var en_ie = moment__default.defineLocale('en-ie', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + ordinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : New Zealand english (en-nz) + + var en_nz = moment__default.defineLocale('en-nz', { + months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), + weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), + weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), + weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' + }, + ordinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : esperanto (eo) + //! author : Colin Dean : https://github.com/colindean + //! komento: Mi estas malcerta se mi korekte traktis akuzativojn en tiu traduko. + //! Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni! + + var eo = moment__default.defineLocale('eo', { + months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'), + weekdays : 'Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato'.split('_'), + weekdaysShort : 'Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab'.split('_'), + weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D[-an de] MMMM, YYYY', + LLL : 'D[-an de] MMMM, YYYY HH:mm', + LLLL : 'dddd, [la] D[-an de] MMMM, YYYY HH:mm' + }, + meridiemParse: /[ap]\.t\.m/i, + isPM: function (input) { + return input.charAt(0).toLowerCase() === 'p'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'p.t.m.' : 'P.T.M.'; + } else { + return isLower ? 'a.t.m.' : 'A.T.M.'; + } + }, + calendar : { + sameDay : '[Hodiaŭ je] LT', + nextDay : '[Morgaŭ je] LT', + nextWeek : 'dddd [je] LT', + lastDay : '[Hieraŭ je] LT', + lastWeek : '[pasinta] dddd [je] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'je %s', + past : 'antaŭ %s', + s : 'sekundoj', + m : 'minuto', + mm : '%d minutoj', + h : 'horo', + hh : '%d horoj', + d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo + dd : '%d tagoj', + M : 'monato', + MM : '%d monatoj', + y : 'jaro', + yy : '%d jaroj' + }, + ordinalParse: /\d{1,2}a/, + ordinal : '%da', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : spanish (es) + //! author : Julio Napurí : https://github.com/julionc + + var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), + es__monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); + + var es = moment__default.defineLocale('es', { + months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), + monthsShort : function (m, format) { + if (/-MMM-/.test(format)) { + return es__monthsShort[m.month()]; + } else { + return monthsShortDot[m.month()]; + } + }, + weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), + weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), + weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY H:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm' + }, + calendar : { + sameDay : function () { + return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextDay : function () { + return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + nextWeek : function () { + return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastDay : function () { + return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + lastWeek : function () { + return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'en %s', + past : 'hace %s', + s : 'unos segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'una hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un año', + yy : '%d años' + }, + ordinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : estonian (et) + //! author : Henry Kehlmann : https://github.com/madhenry + //! improvements : Illimar Tambek : https://github.com/ragulka + + function et__processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'], + 'm' : ['ühe minuti', 'üks minut'], + 'mm': [number + ' minuti', number + ' minutit'], + 'h' : ['ühe tunni', 'tund aega', 'üks tund'], + 'hh': [number + ' tunni', number + ' tundi'], + 'd' : ['ühe päeva', 'üks päev'], + 'M' : ['kuu aja', 'kuu aega', 'üks kuu'], + 'MM': [number + ' kuu', number + ' kuud'], + 'y' : ['ühe aasta', 'aasta', 'üks aasta'], + 'yy': [number + ' aasta', number + ' aastat'] + }; + if (withoutSuffix) { + return format[key][2] ? format[key][2] : format[key][1]; + } + return isFuture ? format[key][0] : format[key][1]; + } + + var et = moment__default.defineLocale('et', { + months : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'), + monthsShort : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'), + weekdays : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'), + weekdaysShort : 'P_E_T_K_N_R_L'.split('_'), + weekdaysMin : 'P_E_T_K_N_R_L'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[Täna,] LT', + nextDay : '[Homme,] LT', + nextWeek : '[Järgmine] dddd LT', + lastDay : '[Eile,] LT', + lastWeek : '[Eelmine] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s pärast', + past : '%s tagasi', + s : et__processRelativeTime, + m : et__processRelativeTime, + mm : et__processRelativeTime, + h : et__processRelativeTime, + hh : et__processRelativeTime, + d : et__processRelativeTime, + dd : '%d päeva', + M : et__processRelativeTime, + MM : et__processRelativeTime, + y : et__processRelativeTime, + yy : et__processRelativeTime + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : euskara (eu) + //! author : Eneko Illarramendi : https://github.com/eillarra + + var eu = moment__default.defineLocale('eu', { + months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'), + monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'), + weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'), + weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'), + weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'YYYY[ko] MMMM[ren] D[a]', + LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm', + LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm', + l : 'YYYY-M-D', + ll : 'YYYY[ko] MMM D[a]', + lll : 'YYYY[ko] MMM D[a] HH:mm', + llll : 'ddd, YYYY[ko] MMM D[a] HH:mm' + }, + calendar : { + sameDay : '[gaur] LT[etan]', + nextDay : '[bihar] LT[etan]', + nextWeek : 'dddd LT[etan]', + lastDay : '[atzo] LT[etan]', + lastWeek : '[aurreko] dddd LT[etan]', + sameElse : 'L' + }, + relativeTime : { + future : '%s barru', + past : 'duela %s', + s : 'segundo batzuk', + m : 'minutu bat', + mm : '%d minutu', + h : 'ordu bat', + hh : '%d ordu', + d : 'egun bat', + dd : '%d egun', + M : 'hilabete bat', + MM : '%d hilabete', + y : 'urte bat', + yy : '%d urte' + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Persian (fa) + //! author : Ebrahim Byagowi : https://github.com/ebraminio + + var fa__symbolMap = { + '1': '۱', + '2': '۲', + '3': '۳', + '4': '۴', + '5': '۵', + '6': '۶', + '7': '۷', + '8': '۸', + '9': '۹', + '0': '۰' + }, fa__numberMap = { + '۱': '1', + '۲': '2', + '۳': '3', + '۴': '4', + '۵': '5', + '۶': '6', + '۷': '7', + '۸': '8', + '۹': '9', + '۰': '0' + }; + + var fa = moment__default.defineLocale('fa', { + months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), + monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), + weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), + weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), + weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + meridiemParse: /قبل از ظهر|بعد از ظهر/, + isPM: function (input) { + return /بعد از ظهر/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'قبل از ظهر'; + } else { + return 'بعد از ظهر'; + } + }, + calendar : { + sameDay : '[امروز ساعت] LT', + nextDay : '[فردا ساعت] LT', + nextWeek : 'dddd [ساعت] LT', + lastDay : '[دیروز ساعت] LT', + lastWeek : 'dddd [پیش] [ساعت] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'در %s', + past : '%s پیش', + s : 'چندین ثانیه', + m : 'یک دقیقه', + mm : '%d دقیقه', + h : 'یک ساعت', + hh : '%d ساعت', + d : 'یک روز', + dd : '%d روز', + M : 'یک ماه', + MM : '%d ماه', + y : 'یک سال', + yy : '%d سال' + }, + preparse: function (string) { + return string.replace(/[۰-۹]/g, function (match) { + return fa__numberMap[match]; + }).replace(/،/g, ','); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return fa__symbolMap[match]; + }).replace(/,/g, '،'); + }, + ordinalParse: /\d{1,2}م/, + ordinal : '%dم', + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : finnish (fi) + //! author : Tarmo Aidantausta : https://github.com/bleadof + + var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '), + numbersFuture = [ + 'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden', + numbersPast[7], numbersPast[8], numbersPast[9] + ]; + function fi__translate(number, withoutSuffix, key, isFuture) { + var result = ''; + switch (key) { + case 's': + return isFuture ? 'muutaman sekunnin' : 'muutama sekunti'; + case 'm': + return isFuture ? 'minuutin' : 'minuutti'; + case 'mm': + result = isFuture ? 'minuutin' : 'minuuttia'; + break; + case 'h': + return isFuture ? 'tunnin' : 'tunti'; + case 'hh': + result = isFuture ? 'tunnin' : 'tuntia'; + break; + case 'd': + return isFuture ? 'päivän' : 'päivä'; + case 'dd': + result = isFuture ? 'päivän' : 'päivää'; + break; + case 'M': + return isFuture ? 'kuukauden' : 'kuukausi'; + case 'MM': + result = isFuture ? 'kuukauden' : 'kuukautta'; + break; + case 'y': + return isFuture ? 'vuoden' : 'vuosi'; + case 'yy': + result = isFuture ? 'vuoden' : 'vuotta'; + break; + } + result = verbalNumber(number, isFuture) + ' ' + result; + return result; + } + function verbalNumber(number, isFuture) { + return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number; + } + + var fi = moment__default.defineLocale('fi', { + months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'), + monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'), + weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'), + weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'), + weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD.MM.YYYY', + LL : 'Do MMMM[ta] YYYY', + LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm', + LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm', + l : 'D.M.YYYY', + ll : 'Do MMM YYYY', + lll : 'Do MMM YYYY, [klo] HH.mm', + llll : 'ddd, Do MMM YYYY, [klo] HH.mm' + }, + calendar : { + sameDay : '[tänään] [klo] LT', + nextDay : '[huomenna] [klo] LT', + nextWeek : 'dddd [klo] LT', + lastDay : '[eilen] [klo] LT', + lastWeek : '[viime] dddd[na] [klo] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s päästä', + past : '%s sitten', + s : fi__translate, + m : fi__translate, + mm : fi__translate, + h : fi__translate, + hh : fi__translate, + d : fi__translate, + dd : fi__translate, + M : fi__translate, + MM : fi__translate, + y : fi__translate, + yy : fi__translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : faroese (fo) + //! author : Ragnar Johannesen : https://github.com/ragnar123 + + var fo = moment__default.defineLocale('fo', { + months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), + weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'), + weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'), + weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D. MMMM, YYYY HH:mm' + }, + calendar : { + sameDay : '[Í dag kl.] LT', + nextDay : '[Í morgin kl.] LT', + nextWeek : 'dddd [kl.] LT', + lastDay : '[Í gjár kl.] LT', + lastWeek : '[síðstu] dddd [kl] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'um %s', + past : '%s síðani', + s : 'fá sekund', + m : 'ein minutt', + mm : '%d minuttir', + h : 'ein tími', + hh : '%d tímar', + d : 'ein dagur', + dd : '%d dagar', + M : 'ein mánaði', + MM : '%d mánaðir', + y : 'eitt ár', + yy : '%d ár' + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : canadian french (fr-ca) + //! author : Jonathan Abourbih : https://github.com/jonbca + + var fr_ca = moment__default.defineLocale('fr-ca', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Aujourd\'hui à] LT', + nextDay: '[Demain à] LT', + nextWeek: 'dddd [à] LT', + lastDay: '[Hier à] LT', + lastWeek: 'dddd [dernier à] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + ordinalParse: /\d{1,2}(er|e)/, + ordinal : function (number) { + return number + (number === 1 ? 'er' : 'e'); + } + }); + + //! moment.js locale configuration + //! locale : swiss french (fr) + //! author : Gaspard Bucher : https://github.com/gaspard + + var fr_ch = moment__default.defineLocale('fr-ch', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Aujourd\'hui à] LT', + nextDay: '[Demain à] LT', + nextWeek: 'dddd [à] LT', + lastDay: '[Hier à] LT', + lastWeek: 'dddd [dernier à] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + ordinalParse: /\d{1,2}(er|e)/, + ordinal : function (number) { + return number + (number === 1 ? 'er' : 'e'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : french (fr) + //! author : John Fischer : https://github.com/jfroffice + + var fr = moment__default.defineLocale('fr', { + months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), + monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), + weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), + weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), + weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Aujourd\'hui à] LT', + nextDay: '[Demain à] LT', + nextWeek: 'dddd [à] LT', + lastDay: '[Hier à] LT', + lastWeek: 'dddd [dernier à] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'dans %s', + past : 'il y a %s', + s : 'quelques secondes', + m : 'une minute', + mm : '%d minutes', + h : 'une heure', + hh : '%d heures', + d : 'un jour', + dd : '%d jours', + M : 'un mois', + MM : '%d mois', + y : 'un an', + yy : '%d ans' + }, + ordinalParse: /\d{1,2}(er|)/, + ordinal : function (number) { + return number + (number === 1 ? 'er' : ''); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : frisian (fy) + //! author : Robin van der Vliet : https://github.com/robin0van0der0v + + var fy__monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'), + fy__monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'); + + var fy = moment__default.defineLocale('fy', { + months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'), + monthsShort : function (m, format) { + if (/-MMM-/.test(format)) { + return fy__monthsShortWithoutDots[m.month()]; + } else { + return fy__monthsShortWithDots[m.month()]; + } + }, + weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'), + weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'), + weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[hjoed om] LT', + nextDay: '[moarn om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[juster om] LT', + lastWeek: '[ôfrûne] dddd [om] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'oer %s', + past : '%s lyn', + s : 'in pear sekonden', + m : 'ien minút', + mm : '%d minuten', + h : 'ien oere', + hh : '%d oeren', + d : 'ien dei', + dd : '%d dagen', + M : 'ien moanne', + MM : '%d moannen', + y : 'ien jier', + yy : '%d jierren' + }, + ordinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : great britain scottish gealic (gd) + //! author : Jon Ashdown : https://github.com/jonashdown + + var gd__months = [ + 'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd' + ]; + + var gd__monthsShort = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh']; + + var gd__weekdays = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne']; + + var weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis']; + + var weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa']; + + var gd = moment__default.defineLocale('gd', { + months : gd__months, + monthsShort : gd__monthsShort, + monthsParseExact : true, + weekdays : gd__weekdays, + weekdaysShort : weekdaysShort, + weekdaysMin : weekdaysMin, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[An-diugh aig] LT', + nextDay : '[A-màireach aig] LT', + nextWeek : 'dddd [aig] LT', + lastDay : '[An-dè aig] LT', + lastWeek : 'dddd [seo chaidh] [aig] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ann an %s', + past : 'bho chionn %s', + s : 'beagan diogan', + m : 'mionaid', + mm : '%d mionaidean', + h : 'uair', + hh : '%d uairean', + d : 'latha', + dd : '%d latha', + M : 'mìos', + MM : '%d mìosan', + y : 'bliadhna', + yy : '%d bliadhna' + }, + ordinalParse : /\d{1,2}(d|na|mh)/, + ordinal : function (number) { + var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : galician (gl) + //! author : Juan G. Hurtado : https://github.com/juanghurtado + + var gl = moment__default.defineLocale('gl', { + months : 'Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro'.split('_'), + monthsShort : 'Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.'.split('_'), + weekdays : 'Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado'.split('_'), + weekdaysShort : 'Dom._Lun._Mar._Mér._Xov._Ven._Sáb.'.split('_'), + weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd D MMMM YYYY H:mm' + }, + calendar : { + sameDay : function () { + return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; + }, + nextDay : function () { + return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; + }, + nextWeek : function () { + return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; + }, + lastDay : function () { + return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT'; + }, + lastWeek : function () { + return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; + }, + sameElse : 'L' + }, + relativeTime : { + future : function (str) { + if (str === 'uns segundos') { + return 'nuns segundos'; + } + return 'en ' + str; + }, + past : 'hai %s', + s : 'uns segundos', + m : 'un minuto', + mm : '%d minutos', + h : 'unha hora', + hh : '%d horas', + d : 'un día', + dd : '%d días', + M : 'un mes', + MM : '%d meses', + y : 'un ano', + yy : '%d anos' + }, + ordinalParse : /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Hebrew (he) + //! author : Tomer Cohen : https://github.com/tomer + //! author : Moshe Simantov : https://github.com/DevelopmentIL + //! author : Tal Ater : https://github.com/TalAter + + var he = moment__default.defineLocale('he', { + months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'), + monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'), + weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'), + weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'), + weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [ב]MMMM YYYY', + LLL : 'D [ב]MMMM YYYY HH:mm', + LLLL : 'dddd, D [ב]MMMM YYYY HH:mm', + l : 'D/M/YYYY', + ll : 'D MMM YYYY', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd, D MMM YYYY HH:mm' + }, + calendar : { + sameDay : '[היום ב־]LT', + nextDay : '[מחר ב־]LT', + nextWeek : 'dddd [בשעה] LT', + lastDay : '[אתמול ב־]LT', + lastWeek : '[ביום] dddd [האחרון בשעה] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'בעוד %s', + past : 'לפני %s', + s : 'מספר שניות', + m : 'דקה', + mm : '%d דקות', + h : 'שעה', + hh : function (number) { + if (number === 2) { + return 'שעתיים'; + } + return number + ' שעות'; + }, + d : 'יום', + dd : function (number) { + if (number === 2) { + return 'יומיים'; + } + return number + ' ימים'; + }, + M : 'חודש', + MM : function (number) { + if (number === 2) { + return 'חודשיים'; + } + return number + ' חודשים'; + }, + y : 'שנה', + yy : function (number) { + if (number === 2) { + return 'שנתיים'; + } else if (number % 10 === 0 && number !== 10) { + return number + ' שנה'; + } + return number + ' שנים'; + } + }, + meridiemParse: /אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i, + isPM : function (input) { + return /^(אחה"צ|אחרי הצהריים|בערב)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 5) { + return 'לפנות בוקר'; + } else if (hour < 10) { + return 'בבוקר'; + } else if (hour < 12) { + return isLower ? 'לפנה"צ' : 'לפני הצהריים'; + } else if (hour < 18) { + return isLower ? 'אחה"צ' : 'אחרי הצהריים'; + } else { + return 'בערב'; + } + } + }); + + //! moment.js locale configuration + //! locale : hindi (hi) + //! author : Mayank Singhal : https://github.com/mayanksinghal + + var hi__symbolMap = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' + }, + hi__numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' + }; + + var hi = moment__default.defineLocale('hi', { + months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'), + monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'), + weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), + weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'), + weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), + longDateFormat : { + LT : 'A h:mm बजे', + LTS : 'A h:mm:ss बजे', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm बजे', + LLLL : 'dddd, D MMMM YYYY, A h:mm बजे' + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[कल] LT', + nextWeek : 'dddd, LT', + lastDay : '[कल] LT', + lastWeek : '[पिछले] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s में', + past : '%s पहले', + s : 'कुछ ही क्षण', + m : 'एक मिनट', + mm : '%d मिनट', + h : 'एक घंटा', + hh : '%d घंटे', + d : 'एक दिन', + dd : '%d दिन', + M : 'एक महीने', + MM : '%d महीने', + y : 'एक वर्ष', + yy : '%d वर्ष' + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return hi__numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return hi__symbolMap[match]; + }); + }, + // Hindi notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi. + meridiemParse: /रात|सुबह|दोपहर|शाम/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'रात') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'सुबह') { + return hour; + } else if (meridiem === 'दोपहर') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'शाम') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'रात'; + } else if (hour < 10) { + return 'सुबह'; + } else if (hour < 17) { + return 'दोपहर'; + } else if (hour < 20) { + return 'शाम'; + } else { + return 'रात'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : hrvatski (hr) + //! author : Bojan Marković : https://github.com/bmarkovic + + function hr__translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'm': + return withoutSuffix ? 'jedna minuta' : 'jedne minute'; + case 'mm': + if (number === 1) { + result += 'minuta'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'minute'; + } else { + result += 'minuta'; + } + return result; + case 'h': + return withoutSuffix ? 'jedan sat' : 'jednog sata'; + case 'hh': + if (number === 1) { + result += 'sat'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'sata'; + } else { + result += 'sati'; + } + return result; + case 'dd': + if (number === 1) { + result += 'dan'; + } else { + result += 'dana'; + } + return result; + case 'MM': + if (number === 1) { + result += 'mjesec'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'mjeseca'; + } else { + result += 'mjeseci'; + } + return result; + case 'yy': + if (number === 1) { + result += 'godina'; + } else if (number === 2 || number === 3 || number === 4) { + result += 'godine'; + } else { + result += 'godina'; + } + return result; + } + } + + var hr = moment__default.defineLocale('hr', { + months : { + format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'), + standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_') + }, + monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'), + weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), + weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), + weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD. MM. YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[danas u] LT', + nextDay : '[sutra u] LT', + nextWeek : function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[jučer u] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + return '[prošlu] dddd [u] LT'; + case 6: + return '[prošle] [subote] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prošli] dddd [u] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'prije %s', + s : 'par sekundi', + m : hr__translate, + mm : hr__translate, + h : hr__translate, + hh : hr__translate, + d : 'dan', + dd : hr__translate, + M : 'mjesec', + MM : hr__translate, + y : 'godinu', + yy : hr__translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : hungarian (hu) + //! author : Adam Brunner : https://github.com/adambrunner + + var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' '); + function hu__translate(number, withoutSuffix, key, isFuture) { + var num = number, + suffix; + switch (key) { + case 's': + return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce'; + case 'm': + return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce'); + case 'mm': + return num + (isFuture || withoutSuffix ? ' perc' : ' perce'); + case 'h': + return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája'); + case 'hh': + return num + (isFuture || withoutSuffix ? ' óra' : ' órája'); + case 'd': + return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja'); + case 'dd': + return num + (isFuture || withoutSuffix ? ' nap' : ' napja'); + case 'M': + return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); + case 'MM': + return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); + case 'y': + return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve'); + case 'yy': + return num + (isFuture || withoutSuffix ? ' év' : ' éve'); + } + return ''; + } + function week(isFuture) { + return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]'; + } + + var hu = moment__default.defineLocale('hu', { + months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'), + monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'), + weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'), + weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'), + weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'YYYY.MM.DD.', + LL : 'YYYY. MMMM D.', + LLL : 'YYYY. MMMM D. H:mm', + LLLL : 'YYYY. MMMM D., dddd H:mm' + }, + meridiemParse: /de|du/i, + isPM: function (input) { + return input.charAt(1).toLowerCase() === 'u'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower === true ? 'de' : 'DE'; + } else { + return isLower === true ? 'du' : 'DU'; + } + }, + calendar : { + sameDay : '[ma] LT[-kor]', + nextDay : '[holnap] LT[-kor]', + nextWeek : function () { + return week.call(this, true); + }, + lastDay : '[tegnap] LT[-kor]', + lastWeek : function () { + return week.call(this, false); + }, + sameElse : 'L' + }, + relativeTime : { + future : '%s múlva', + past : '%s', + s : hu__translate, + m : hu__translate, + mm : hu__translate, + h : hu__translate, + hh : hu__translate, + d : hu__translate, + dd : hu__translate, + M : hu__translate, + MM : hu__translate, + y : hu__translate, + yy : hu__translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Armenian (hy-am) + //! author : Armendarabyan : https://github.com/armendarabyan + + var hy_am = moment__default.defineLocale('hy-am', { + months : { + format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'), + standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_') + }, + monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'), + weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'), + weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), + weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY թ.', + LLL : 'D MMMM YYYY թ., HH:mm', + LLLL : 'dddd, D MMMM YYYY թ., HH:mm' + }, + calendar : { + sameDay: '[այսօր] LT', + nextDay: '[վաղը] LT', + lastDay: '[երեկ] LT', + nextWeek: function () { + return 'dddd [օրը ժամը] LT'; + }, + lastWeek: function () { + return '[անցած] dddd [օրը ժամը] LT'; + }, + sameElse: 'L' + }, + relativeTime : { + future : '%s հետո', + past : '%s առաջ', + s : 'մի քանի վայրկյան', + m : 'րոպե', + mm : '%d րոպե', + h : 'ժամ', + hh : '%d ժամ', + d : 'օր', + dd : '%d օր', + M : 'ամիս', + MM : '%d ամիս', + y : 'տարի', + yy : '%d տարի' + }, + meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/, + isPM: function (input) { + return /^(ցերեկվա|երեկոյան)$/.test(input); + }, + meridiem : function (hour) { + if (hour < 4) { + return 'գիշերվա'; + } else if (hour < 12) { + return 'առավոտվա'; + } else if (hour < 17) { + return 'ցերեկվա'; + } else { + return 'երեկոյան'; + } + }, + ordinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/, + ordinal: function (number, period) { + switch (period) { + case 'DDD': + case 'w': + case 'W': + case 'DDDo': + if (number === 1) { + return number + '-ին'; + } + return number + '-րդ'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Bahasa Indonesia (id) + //! author : Mohammad Satrio Utomo : https://github.com/tyok + //! reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan + + var id = moment__default.defineLocale('id', { + months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'), + weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'), + weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|siang|sore|malam/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'siang') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'sore' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'siang'; + } else if (hours < 19) { + return 'sore'; + } else { + return 'malam'; + } + }, + calendar : { + sameDay : '[Hari ini pukul] LT', + nextDay : '[Besok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kemarin pukul] LT', + lastWeek : 'dddd [lalu pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dalam %s', + past : '%s yang lalu', + s : 'beberapa detik', + m : 'semenit', + mm : '%d menit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : icelandic (is) + //! author : Hinrik Örn Sigurðsson : https://github.com/hinrik + + function is__plural(n) { + if (n % 100 === 11) { + return true; + } else if (n % 10 === 1) { + return false; + } + return true; + } + function is__translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': + return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum'; + case 'm': + return withoutSuffix ? 'mínúta' : 'mínútu'; + case 'mm': + if (is__plural(number)) { + return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum'); + } else if (withoutSuffix) { + return result + 'mínúta'; + } + return result + 'mínútu'; + case 'hh': + if (is__plural(number)) { + return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum'); + } + return result + 'klukkustund'; + case 'd': + if (withoutSuffix) { + return 'dagur'; + } + return isFuture ? 'dag' : 'degi'; + case 'dd': + if (is__plural(number)) { + if (withoutSuffix) { + return result + 'dagar'; + } + return result + (isFuture ? 'daga' : 'dögum'); + } else if (withoutSuffix) { + return result + 'dagur'; + } + return result + (isFuture ? 'dag' : 'degi'); + case 'M': + if (withoutSuffix) { + return 'mánuður'; + } + return isFuture ? 'mánuð' : 'mánuði'; + case 'MM': + if (is__plural(number)) { + if (withoutSuffix) { + return result + 'mánuðir'; + } + return result + (isFuture ? 'mánuði' : 'mánuðum'); + } else if (withoutSuffix) { + return result + 'mánuður'; + } + return result + (isFuture ? 'mánuð' : 'mánuði'); + case 'y': + return withoutSuffix || isFuture ? 'ár' : 'ári'; + case 'yy': + if (is__plural(number)) { + return result + (withoutSuffix || isFuture ? 'ár' : 'árum'); + } + return result + (withoutSuffix || isFuture ? 'ár' : 'ári'); + } + } + + var is = moment__default.defineLocale('is', { + months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'), + weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'), + weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'), + weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] H:mm', + LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm' + }, + calendar : { + sameDay : '[í dag kl.] LT', + nextDay : '[á morgun kl.] LT', + nextWeek : 'dddd [kl.] LT', + lastDay : '[í gær kl.] LT', + lastWeek : '[síðasta] dddd [kl.] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'eftir %s', + past : 'fyrir %s síðan', + s : is__translate, + m : is__translate, + mm : is__translate, + h : 'klukkustund', + hh : is__translate, + d : is__translate, + dd : is__translate, + M : is__translate, + MM : is__translate, + y : is__translate, + yy : is__translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : italian (it) + //! author : Lorenzo : https://github.com/aliem + //! author: Mattia Larentis: https://github.com/nostalgiaz + + var it = moment__default.defineLocale('it', { + months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'), + monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'), + weekdays : 'Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato'.split('_'), + weekdaysShort : 'Dom_Lun_Mar_Mer_Gio_Ven_Sab'.split('_'), + weekdaysMin : 'Do_Lu_Ma_Me_Gi_Ve_Sa'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Oggi alle] LT', + nextDay: '[Domani alle] LT', + nextWeek: 'dddd [alle] LT', + lastDay: '[Ieri alle] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[la scorsa] dddd [alle] LT'; + default: + return '[lo scorso] dddd [alle] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : function (s) { + return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s; + }, + past : '%s fa', + s : 'alcuni secondi', + m : 'un minuto', + mm : '%d minuti', + h : 'un\'ora', + hh : '%d ore', + d : 'un giorno', + dd : '%d giorni', + M : 'un mese', + MM : '%d mesi', + y : 'un anno', + yy : '%d anni' + }, + ordinalParse : /\d{1,2}º/, + ordinal: '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : japanese (ja) + //! author : LI Long : https://github.com/baryon + + var ja = moment__default.defineLocale('ja', { + months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'), + weekdaysShort : '日_月_火_水_木_金_土'.split('_'), + weekdaysMin : '日_月_火_水_木_金_土'.split('_'), + longDateFormat : { + LT : 'Ah時m分', + LTS : 'Ah時m分s秒', + L : 'YYYY/MM/DD', + LL : 'YYYY年M月D日', + LLL : 'YYYY年M月D日Ah時m分', + LLLL : 'YYYY年M月D日Ah時m分 dddd' + }, + meridiemParse: /午前|午後/i, + isPM : function (input) { + return input === '午後'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return '午前'; + } else { + return '午後'; + } + }, + calendar : { + sameDay : '[今日] LT', + nextDay : '[明日] LT', + nextWeek : '[来週]dddd LT', + lastDay : '[昨日] LT', + lastWeek : '[前週]dddd LT', + sameElse : 'L' + }, + ordinalParse : /\d{1,2}日/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + default: + return number; + } + }, + relativeTime : { + future : '%s後', + past : '%s前', + s : '数秒', + m : '1分', + mm : '%d分', + h : '1時間', + hh : '%d時間', + d : '1日', + dd : '%d日', + M : '1ヶ月', + MM : '%dヶ月', + y : '1年', + yy : '%d年' + } + }); + + //! moment.js locale configuration + //! locale : Boso Jowo (jv) + //! author : Rony Lantip : https://github.com/lantip + //! reference: http://jv.wikipedia.org/wiki/Basa_Jawa + + var jv = moment__default.defineLocale('jv', { + months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'), + monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'), + weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'), + weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'), + weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /enjing|siyang|sonten|ndalu/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'enjing') { + return hour; + } else if (meridiem === 'siyang') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'sonten' || meridiem === 'ndalu') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'enjing'; + } else if (hours < 15) { + return 'siyang'; + } else if (hours < 19) { + return 'sonten'; + } else { + return 'ndalu'; + } + }, + calendar : { + sameDay : '[Dinten puniko pukul] LT', + nextDay : '[Mbenjang pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kala wingi pukul] LT', + lastWeek : 'dddd [kepengker pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'wonten ing %s', + past : '%s ingkang kepengker', + s : 'sawetawis detik', + m : 'setunggal menit', + mm : '%d menit', + h : 'setunggal jam', + hh : '%d jam', + d : 'sedinten', + dd : '%d dinten', + M : 'sewulan', + MM : '%d wulan', + y : 'setaun', + yy : '%d taun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Georgian (ka) + //! author : Irakli Janiashvili : https://github.com/irakli-janiashvili + + var ka = moment__default.defineLocale('ka', { + months : { + standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'), + format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_') + }, + monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'), + weekdays : { + standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'), + format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'), + isFormat: /(წინა|შემდეგ)/ + }, + weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'), + weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'), + longDateFormat : { + LT : 'h:mm A', + LTS : 'h:mm:ss A', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY h:mm A', + LLLL : 'dddd, D MMMM YYYY h:mm A' + }, + calendar : { + sameDay : '[დღეს] LT[-ზე]', + nextDay : '[ხვალ] LT[-ზე]', + lastDay : '[გუშინ] LT[-ზე]', + nextWeek : '[შემდეგ] dddd LT[-ზე]', + lastWeek : '[წინა] dddd LT-ზე', + sameElse : 'L' + }, + relativeTime : { + future : function (s) { + return (/(წამი|წუთი|საათი|წელი)/).test(s) ? + s.replace(/ი$/, 'ში') : + s + 'ში'; + }, + past : function (s) { + if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) { + return s.replace(/(ი|ე)$/, 'ის წინ'); + } + if ((/წელი/).test(s)) { + return s.replace(/წელი$/, 'წლის წინ'); + } + }, + s : 'რამდენიმე წამი', + m : 'წუთი', + mm : '%d წუთი', + h : 'საათი', + hh : '%d საათი', + d : 'დღე', + dd : '%d დღე', + M : 'თვე', + MM : '%d თვე', + y : 'წელი', + yy : '%d წელი' + }, + ordinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/, + ordinal : function (number) { + if (number === 0) { + return number; + } + if (number === 1) { + return number + '-ლი'; + } + if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) { + return 'მე-' + number; + } + return number + '-ე'; + }, + week : { + dow : 1, + doy : 7 + } + }); + + //! moment.js locale configuration + //! locale : kazakh (kk) + //! authors : Nurlan Rakhimzhanov : https://github.com/nurlan + + var kk__suffixes = { + 0: '-ші', + 1: '-ші', + 2: '-ші', + 3: '-ші', + 4: '-ші', + 5: '-ші', + 6: '-шы', + 7: '-ші', + 8: '-ші', + 9: '-шы', + 10: '-шы', + 20: '-шы', + 30: '-шы', + 40: '-шы', + 50: '-ші', + 60: '-шы', + 70: '-ші', + 80: '-ші', + 90: '-шы', + 100: '-ші' + }; + + var kk = moment__default.defineLocale('kk', { + months : 'Қаңтар_Ақпан_Наурыз_Сәуір_Мамыр_Маусым_Шілде_Тамыз_Қыркүйек_Қазан_Қараша_Желтоқсан'.split('_'), + monthsShort : 'Қаң_Ақп_Нау_Сәу_Мам_Мау_Шіл_Там_Қыр_Қаз_Қар_Жел'.split('_'), + weekdays : 'Жексенбі_Дүйсенбі_Сейсенбі_Сәрсенбі_Бейсенбі_Жұма_Сенбі'.split('_'), + weekdaysShort : 'Жек_Дүй_Сей_Сәр_Бей_Жұм_Сен'.split('_'), + weekdaysMin : 'Жк_Дй_Сй_Ср_Бй_Жм_Сн'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Бүгін сағат] LT', + nextDay : '[Ертең сағат] LT', + nextWeek : 'dddd [сағат] LT', + lastDay : '[Кеше сағат] LT', + lastWeek : '[Өткен аптаның] dddd [сағат] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ішінде', + past : '%s бұрын', + s : 'бірнеше секунд', + m : 'бір минут', + mm : '%d минут', + h : 'бір сағат', + hh : '%d сағат', + d : 'бір күн', + dd : '%d күн', + M : 'бір ай', + MM : '%d ай', + y : 'бір жыл', + yy : '%d жыл' + }, + ordinalParse: /\d{1,2}-(ші|шы)/, + ordinal : function (number) { + var a = number % 10, + b = number >= 100 ? 100 : null; + return number + (kk__suffixes[number] || kk__suffixes[a] || kk__suffixes[b]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : khmer (km) + //! author : Kruy Vanna : https://github.com/kruyvanna + + var km = moment__default.defineLocale('km', { + months: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'), + monthsShort: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'), + weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), + weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), + weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), + longDateFormat: { + LT: 'HH:mm', + LTS : 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd, D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[ថ្ងៃនេះ ម៉ោង] LT', + nextDay: '[ស្អែក ម៉ោង] LT', + nextWeek: 'dddd [ម៉ោង] LT', + lastDay: '[ម្សិលមិញ ម៉ោង] LT', + lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT', + sameElse: 'L' + }, + relativeTime: { + future: '%sទៀត', + past: '%sមុន', + s: 'ប៉ុន្មានវិនាទី', + m: 'មួយនាទី', + mm: '%d នាទី', + h: 'មួយម៉ោង', + hh: '%d ម៉ោង', + d: 'មួយថ្ងៃ', + dd: '%d ថ្ងៃ', + M: 'មួយខែ', + MM: '%d ខែ', + y: 'មួយឆ្នាំ', + yy: '%d ឆ្នាំ' + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : korean (ko) + //! + //! authors + //! + //! - Kyungwook, Park : https://github.com/kyungw00k + //! - Jeeeyul Lee + + var ko = moment__default.defineLocale('ko', { + months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), + monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), + weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'), + weekdaysShort : '일_월_화_수_목_금_토'.split('_'), + weekdaysMin : '일_월_화_수_목_금_토'.split('_'), + longDateFormat : { + LT : 'A h시 m분', + LTS : 'A h시 m분 s초', + L : 'YYYY.MM.DD', + LL : 'YYYY년 MMMM D일', + LLL : 'YYYY년 MMMM D일 A h시 m분', + LLLL : 'YYYY년 MMMM D일 dddd A h시 m분' + }, + calendar : { + sameDay : '오늘 LT', + nextDay : '내일 LT', + nextWeek : 'dddd LT', + lastDay : '어제 LT', + lastWeek : '지난주 dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s 후', + past : '%s 전', + s : '몇초', + ss : '%d초', + m : '일분', + mm : '%d분', + h : '한시간', + hh : '%d시간', + d : '하루', + dd : '%d일', + M : '한달', + MM : '%d달', + y : '일년', + yy : '%d년' + }, + ordinalParse : /\d{1,2}일/, + ordinal : '%d일', + meridiemParse : /오전|오후/, + isPM : function (token) { + return token === '오후'; + }, + meridiem : function (hour, minute, isUpper) { + return hour < 12 ? '오전' : '오후'; + } + }); + + //! moment.js locale configuration + //! locale : Luxembourgish (lb) + //! author : mweimerskirch : https://github.com/mweimerskirch, David Raison : https://github.com/kwisatz + + function lb__processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 'm': ['eng Minutt', 'enger Minutt'], + 'h': ['eng Stonn', 'enger Stonn'], + 'd': ['een Dag', 'engem Dag'], + 'M': ['ee Mount', 'engem Mount'], + 'y': ['ee Joer', 'engem Joer'] + }; + return withoutSuffix ? format[key][0] : format[key][1]; + } + function processFutureTime(string) { + var number = string.substr(0, string.indexOf(' ')); + if (eifelerRegelAppliesToNumber(number)) { + return 'a ' + string; + } + return 'an ' + string; + } + function processPastTime(string) { + var number = string.substr(0, string.indexOf(' ')); + if (eifelerRegelAppliesToNumber(number)) { + return 'viru ' + string; + } + return 'virun ' + string; + } + /** + * Returns true if the word before the given number loses the '-n' ending. + * e.g. 'an 10 Deeg' but 'a 5 Deeg' + * + * @param number {integer} + * @returns {boolean} + */ + function eifelerRegelAppliesToNumber(number) { + number = parseInt(number, 10); + if (isNaN(number)) { + return false; + } + if (number < 0) { + // Negative Number --> always true + return true; + } else if (number < 10) { + // Only 1 digit + if (4 <= number && number <= 7) { + return true; + } + return false; + } else if (number < 100) { + // 2 digits + var lastDigit = number % 10, firstDigit = number / 10; + if (lastDigit === 0) { + return eifelerRegelAppliesToNumber(firstDigit); + } + return eifelerRegelAppliesToNumber(lastDigit); + } else if (number < 10000) { + // 3 or 4 digits --> recursively check first digit + while (number >= 10) { + number = number / 10; + } + return eifelerRegelAppliesToNumber(number); + } else { + // Anything larger than 4 digits: recursively check first n-3 digits + number = number / 1000; + return eifelerRegelAppliesToNumber(number); + } + } + + var lb = moment__default.defineLocale('lb', { + months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), + monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), + weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'), + weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'), + weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'), + longDateFormat: { + LT: 'H:mm [Auer]', + LTS: 'H:mm:ss [Auer]', + L: 'DD.MM.YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm [Auer]', + LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]' + }, + calendar: { + sameDay: '[Haut um] LT', + sameElse: 'L', + nextDay: '[Muer um] LT', + nextWeek: 'dddd [um] LT', + lastDay: '[Gëschter um] LT', + lastWeek: function () { + // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule + switch (this.day()) { + case 2: + case 4: + return '[Leschten] dddd [um] LT'; + default: + return '[Leschte] dddd [um] LT'; + } + } + }, + relativeTime : { + future : processFutureTime, + past : processPastTime, + s : 'e puer Sekonnen', + m : lb__processRelativeTime, + mm : '%d Minutten', + h : lb__processRelativeTime, + hh : '%d Stonnen', + d : lb__processRelativeTime, + dd : '%d Deeg', + M : lb__processRelativeTime, + MM : '%d Méint', + y : lb__processRelativeTime, + yy : '%d Joer' + }, + ordinalParse: /\d{1,2}\./, + ordinal: '%d.', + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : lao (lo) + //! author : Ryan Hart : https://github.com/ryanhart2 + + var lo = moment__default.defineLocale('lo', { + months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), + monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), + weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), + weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), + weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'ວັນdddd D MMMM YYYY HH:mm' + }, + meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/, + isPM: function (input) { + return input === 'ຕອນແລງ'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ຕອນເຊົ້າ'; + } else { + return 'ຕອນແລງ'; + } + }, + calendar : { + sameDay : '[ມື້ນີ້ເວລາ] LT', + nextDay : '[ມື້ອື່ນເວລາ] LT', + nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT', + lastDay : '[ມື້ວານນີ້ເວລາ] LT', + lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'ອີກ %s', + past : '%sຜ່ານມາ', + s : 'ບໍ່ເທົ່າໃດວິນາທີ', + m : '1 ນາທີ', + mm : '%d ນາທີ', + h : '1 ຊົ່ວໂມງ', + hh : '%d ຊົ່ວໂມງ', + d : '1 ມື້', + dd : '%d ມື້', + M : '1 ເດືອນ', + MM : '%d ເດືອນ', + y : '1 ປີ', + yy : '%d ປີ' + }, + ordinalParse: /(ທີ່)\d{1,2}/, + ordinal : function (number) { + return 'ທີ່' + number; + } + }); + + //! moment.js locale configuration + //! locale : Lithuanian (lt) + //! author : Mindaugas Mozūras : https://github.com/mmozuras + + var lt__units = { + 'm' : 'minutė_minutės_minutę', + 'mm': 'minutės_minučių_minutes', + 'h' : 'valanda_valandos_valandą', + 'hh': 'valandos_valandų_valandas', + 'd' : 'diena_dienos_dieną', + 'dd': 'dienos_dienų_dienas', + 'M' : 'mėnuo_mėnesio_mėnesį', + 'MM': 'mėnesiai_mėnesių_mėnesius', + 'y' : 'metai_metų_metus', + 'yy': 'metai_metų_metus' + }; + function translateSeconds(number, withoutSuffix, key, isFuture) { + if (withoutSuffix) { + return 'kelios sekundės'; + } else { + return isFuture ? 'kelių sekundžių' : 'kelias sekundes'; + } + } + function translateSingular(number, withoutSuffix, key, isFuture) { + return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]); + } + function special(number) { + return number % 10 === 0 || (number > 10 && number < 20); + } + function forms(key) { + return lt__units[key].split('_'); + } + function lt__translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + if (number === 1) { + return result + translateSingular(number, withoutSuffix, key[0], isFuture); + } else if (withoutSuffix) { + return result + (special(number) ? forms(key)[1] : forms(key)[0]); + } else { + if (isFuture) { + return result + forms(key)[1]; + } else { + return result + (special(number) ? forms(key)[1] : forms(key)[2]); + } + } + } + var lt = moment__default.defineLocale('lt', { + months : { + format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'), + standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_') + }, + monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'), + weekdays : { + format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'), + standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'), + isFormat: /dddd HH:mm/ + }, + weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'), + weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'YYYY [m.] MMMM D [d.]', + LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', + LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]', + l : 'YYYY-MM-DD', + ll : 'YYYY [m.] MMMM D [d.]', + lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', + llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]' + }, + calendar : { + sameDay : '[Šiandien] LT', + nextDay : '[Rytoj] LT', + nextWeek : 'dddd LT', + lastDay : '[Vakar] LT', + lastWeek : '[Praėjusį] dddd LT', + sameElse : 'L' + }, + relativeTime : { + future : 'po %s', + past : 'prieš %s', + s : translateSeconds, + m : translateSingular, + mm : lt__translate, + h : translateSingular, + hh : lt__translate, + d : translateSingular, + dd : lt__translate, + M : translateSingular, + MM : lt__translate, + y : translateSingular, + yy : lt__translate + }, + ordinalParse: /\d{1,2}-oji/, + ordinal : function (number) { + return number + '-oji'; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : latvian (lv) + //! author : Kristaps Karlsons : https://github.com/skakri + //! author : Jānis Elmeris : https://github.com/JanisE + + var lv__units = { + 'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), + 'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), + 'h': 'stundas_stundām_stunda_stundas'.split('_'), + 'hh': 'stundas_stundām_stunda_stundas'.split('_'), + 'd': 'dienas_dienām_diena_dienas'.split('_'), + 'dd': 'dienas_dienām_diena_dienas'.split('_'), + 'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), + 'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), + 'y': 'gada_gadiem_gads_gadi'.split('_'), + 'yy': 'gada_gadiem_gads_gadi'.split('_') + }; + /** + * @param withoutSuffix boolean true = a length of time; false = before/after a period of time. + */ + function lv__format(forms, number, withoutSuffix) { + if (withoutSuffix) { + // E.g. "21 minūte", "3 minūtes". + return number % 10 === 1 && number !== 11 ? forms[2] : forms[3]; + } else { + // E.g. "21 minūtes" as in "pēc 21 minūtes". + // E.g. "3 minūtēm" as in "pēc 3 minūtēm". + return number % 10 === 1 && number !== 11 ? forms[0] : forms[1]; + } + } + function lv__relativeTimeWithPlural(number, withoutSuffix, key) { + return number + ' ' + lv__format(lv__units[key], number, withoutSuffix); + } + function relativeTimeWithSingular(number, withoutSuffix, key) { + return lv__format(lv__units[key], number, withoutSuffix); + } + function relativeSeconds(number, withoutSuffix) { + return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm'; + } + + var lv = moment__default.defineLocale('lv', { + months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'), + weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'), + weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY.', + LL : 'YYYY. [gada] D. MMMM', + LLL : 'YYYY. [gada] D. MMMM, HH:mm', + LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm' + }, + calendar : { + sameDay : '[Šodien pulksten] LT', + nextDay : '[Rīt pulksten] LT', + nextWeek : 'dddd [pulksten] LT', + lastDay : '[Vakar pulksten] LT', + lastWeek : '[Pagājušā] dddd [pulksten] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'pēc %s', + past : 'pirms %s', + s : relativeSeconds, + m : relativeTimeWithSingular, + mm : lv__relativeTimeWithPlural, + h : relativeTimeWithSingular, + hh : lv__relativeTimeWithPlural, + d : relativeTimeWithSingular, + dd : lv__relativeTimeWithPlural, + M : relativeTimeWithSingular, + MM : lv__relativeTimeWithPlural, + y : relativeTimeWithSingular, + yy : lv__relativeTimeWithPlural + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Montenegrin (me) + //! author : Miodrag Nikač : https://github.com/miodragnikac + + var me__translator = { + words: { //Different grammatical cases + m: ['jedan minut', 'jednog minuta'], + mm: ['minut', 'minuta', 'minuta'], + h: ['jedan sat', 'jednog sata'], + hh: ['sat', 'sata', 'sati'], + dd: ['dan', 'dana', 'dana'], + MM: ['mjesec', 'mjeseca', 'mjeseci'], + yy: ['godina', 'godine', 'godina'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = me__translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + me__translator.correctGrammaticalCase(number, wordKey); + } + } + }; + + var me = moment__default.defineLocale('me', { + months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'], + monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'], + weekdays: ['nedjelja', 'ponedjeljak', 'utorak', 'srijeda', 'četvrtak', 'petak', 'subota'], + weekdaysShort: ['ned.', 'pon.', 'uto.', 'sri.', 'čet.', 'pet.', 'sub.'], + weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'], + longDateFormat: { + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD. MM. YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' + }, + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sjutra u] LT', + + nextWeek: function () { + switch (this.day()) { + case 0: + return '[u] [nedjelju] [u] LT'; + case 3: + return '[u] [srijedu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[juče u] LT', + lastWeek : function () { + var lastWeekDays = [ + '[prošle] [nedjelje] [u] LT', + '[prošlog] [ponedjeljka] [u] LT', + '[prošlog] [utorka] [u] LT', + '[prošle] [srijede] [u] LT', + '[prošlog] [četvrtka] [u] LT', + '[prošlog] [petka] [u] LT', + '[prošle] [subote] [u] LT' + ]; + return lastWeekDays[this.day()]; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'prije %s', + s : 'nekoliko sekundi', + m : me__translator.translate, + mm : me__translator.translate, + h : me__translator.translate, + hh : me__translator.translate, + d : 'dan', + dd : me__translator.translate, + M : 'mjesec', + MM : me__translator.translate, + y : 'godinu', + yy : me__translator.translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : macedonian (mk) + //! author : Borislav Mickov : https://github.com/B0k0 + + var mk = moment__default.defineLocale('mk', { + months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'), + monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'), + weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'), + weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'), + weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'D.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[Денес во] LT', + nextDay : '[Утре во] LT', + nextWeek : '[Во] dddd [во] LT', + lastDay : '[Вчера во] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + case 3: + case 6: + return '[Изминатата] dddd [во] LT'; + case 1: + case 2: + case 4: + case 5: + return '[Изминатиот] dddd [во] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'после %s', + past : 'пред %s', + s : 'неколку секунди', + m : 'минута', + mm : '%d минути', + h : 'час', + hh : '%d часа', + d : 'ден', + dd : '%d дена', + M : 'месец', + MM : '%d месеци', + y : 'година', + yy : '%d години' + }, + ordinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, + ordinal : function (number) { + var lastDigit = number % 10, + last2Digits = number % 100; + if (number === 0) { + return number + '-ев'; + } else if (last2Digits === 0) { + return number + '-ен'; + } else if (last2Digits > 10 && last2Digits < 20) { + return number + '-ти'; + } else if (lastDigit === 1) { + return number + '-ви'; + } else if (lastDigit === 2) { + return number + '-ри'; + } else if (lastDigit === 7 || lastDigit === 8) { + return number + '-ми'; + } else { + return number + '-ти'; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : malayalam (ml) + //! author : Floyd Pink : https://github.com/floydpink + + var ml = moment__default.defineLocale('ml', { + months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'), + monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'), + weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'), + weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'), + weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'), + longDateFormat : { + LT : 'A h:mm -നു', + LTS : 'A h:mm:ss -നു', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm -നു', + LLLL : 'dddd, D MMMM YYYY, A h:mm -നു' + }, + calendar : { + sameDay : '[ഇന്ന്] LT', + nextDay : '[നാളെ] LT', + nextWeek : 'dddd, LT', + lastDay : '[ഇന്നലെ] LT', + lastWeek : '[കഴിഞ്ഞ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s കഴിഞ്ഞ്', + past : '%s മുൻപ്', + s : 'അൽപ നിമിഷങ്ങൾ', + m : 'ഒരു മിനിറ്റ്', + mm : '%d മിനിറ്റ്', + h : 'ഒരു മണിക്കൂർ', + hh : '%d മണിക്കൂർ', + d : 'ഒരു ദിവസം', + dd : '%d ദിവസം', + M : 'ഒരു മാസം', + MM : '%d മാസം', + y : 'ഒരു വർഷം', + yy : '%d വർഷം' + }, + meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if ((meridiem === 'രാത്രി' && hour >= 4) || + meridiem === 'ഉച്ച കഴിഞ്ഞ്' || + meridiem === 'വൈകുന്നേരം') { + return hour + 12; + } else { + return hour; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'രാത്രി'; + } else if (hour < 12) { + return 'രാവിലെ'; + } else if (hour < 17) { + return 'ഉച്ച കഴിഞ്ഞ്'; + } else if (hour < 20) { + return 'വൈകുന്നേരം'; + } else { + return 'രാത്രി'; + } + } + }); + + //! moment.js locale configuration + //! locale : Marathi (mr) + //! author : Harshad Kale : https://github.com/kalehv + //! author : Vivek Athalye : https://github.com/vnathalye + + var mr__symbolMap = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' + }, + mr__numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' + }; + + function relativeTimeMr(number, withoutSuffix, string, isFuture) + { + var output = ''; + if (withoutSuffix) { + switch (string) { + case 's': output = 'काही सेकंद'; break; + case 'm': output = 'एक मिनिट'; break; + case 'mm': output = '%d मिनिटे'; break; + case 'h': output = 'एक तास'; break; + case 'hh': output = '%d तास'; break; + case 'd': output = 'एक दिवस'; break; + case 'dd': output = '%d दिवस'; break; + case 'M': output = 'एक महिना'; break; + case 'MM': output = '%d महिने'; break; + case 'y': output = 'एक वर्ष'; break; + case 'yy': output = '%d वर्षे'; break; + } + } + else { + switch (string) { + case 's': output = 'काही सेकंदां'; break; + case 'm': output = 'एका मिनिटा'; break; + case 'mm': output = '%d मिनिटां'; break; + case 'h': output = 'एका तासा'; break; + case 'hh': output = '%d तासां'; break; + case 'd': output = 'एका दिवसा'; break; + case 'dd': output = '%d दिवसां'; break; + case 'M': output = 'एका महिन्या'; break; + case 'MM': output = '%d महिन्यां'; break; + case 'y': output = 'एका वर्षा'; break; + case 'yy': output = '%d वर्षां'; break; + } + } + return output.replace(/%d/i, number); + } + + var mr = moment__default.defineLocale('mr', { + months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'), + monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'), + weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), + weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'), + weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), + longDateFormat : { + LT : 'A h:mm वाजता', + LTS : 'A h:mm:ss वाजता', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm वाजता', + LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता' + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[उद्या] LT', + nextWeek : 'dddd, LT', + lastDay : '[काल] LT', + lastWeek: '[मागील] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future: '%sमध्ये', + past: '%sपूर्वी', + s: relativeTimeMr, + m: relativeTimeMr, + mm: relativeTimeMr, + h: relativeTimeMr, + hh: relativeTimeMr, + d: relativeTimeMr, + dd: relativeTimeMr, + M: relativeTimeMr, + MM: relativeTimeMr, + y: relativeTimeMr, + yy: relativeTimeMr + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return mr__numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return mr__symbolMap[match]; + }); + }, + meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'रात्री') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'सकाळी') { + return hour; + } else if (meridiem === 'दुपारी') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'सायंकाळी') { + return hour + 12; + } + }, + meridiem: function (hour, minute, isLower) { + if (hour < 4) { + return 'रात्री'; + } else if (hour < 10) { + return 'सकाळी'; + } else if (hour < 17) { + return 'दुपारी'; + } else if (hour < 20) { + return 'सायंकाळी'; + } else { + return 'रात्री'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Bahasa Malaysia (ms-MY) + //! author : Weldan Jamili : https://github.com/weldan + + var ms_my = moment__default.defineLocale('ms-my', { + months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), + weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), + weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), + weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|tengahari|petang|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'tengahari') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'petang' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'tengahari'; + } else if (hours < 19) { + return 'petang'; + } else { + return 'malam'; + } + }, + calendar : { + sameDay : '[Hari ini pukul] LT', + nextDay : '[Esok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kelmarin pukul] LT', + lastWeek : 'dddd [lepas pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dalam %s', + past : '%s yang lepas', + s : 'beberapa saat', + m : 'seminit', + mm : '%d minit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Bahasa Malaysia (ms-MY) + //! author : Weldan Jamili : https://github.com/weldan + + var locale_ms = moment__default.defineLocale('ms', { + months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), + weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), + weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), + weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY [pukul] HH.mm', + LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' + }, + meridiemParse: /pagi|tengahari|petang|malam/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'pagi') { + return hour; + } else if (meridiem === 'tengahari') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === 'petang' || meridiem === 'malam') { + return hour + 12; + } + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 11) { + return 'pagi'; + } else if (hours < 15) { + return 'tengahari'; + } else if (hours < 19) { + return 'petang'; + } else { + return 'malam'; + } + }, + calendar : { + sameDay : '[Hari ini pukul] LT', + nextDay : '[Esok pukul] LT', + nextWeek : 'dddd [pukul] LT', + lastDay : '[Kelmarin pukul] LT', + lastWeek : 'dddd [lepas pukul] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'dalam %s', + past : '%s yang lepas', + s : 'beberapa saat', + m : 'seminit', + mm : '%d minit', + h : 'sejam', + hh : '%d jam', + d : 'sehari', + dd : '%d hari', + M : 'sebulan', + MM : '%d bulan', + y : 'setahun', + yy : '%d tahun' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Burmese (my) + //! author : Squar team, mysquar.com + + var my__symbolMap = { + '1': '၁', + '2': '၂', + '3': '၃', + '4': '၄', + '5': '၅', + '6': '၆', + '7': '၇', + '8': '၈', + '9': '၉', + '0': '၀' + }, my__numberMap = { + '၁': '1', + '၂': '2', + '၃': '3', + '၄': '4', + '၅': '5', + '၆': '6', + '၇': '7', + '၈': '8', + '၉': '9', + '၀': '0' + }; + + var my = moment__default.defineLocale('my', { + months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'), + monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'), + weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'), + weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), + weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), + + longDateFormat: { + LT: 'HH:mm', + LTS: 'HH:mm:ss', + L: 'DD/MM/YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY HH:mm', + LLLL: 'dddd D MMMM YYYY HH:mm' + }, + calendar: { + sameDay: '[ယနေ.] LT [မှာ]', + nextDay: '[မနက်ဖြန်] LT [မှာ]', + nextWeek: 'dddd LT [မှာ]', + lastDay: '[မနေ.က] LT [မှာ]', + lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]', + sameElse: 'L' + }, + relativeTime: { + future: 'လာမည့် %s မှာ', + past: 'လွန်ခဲ့သော %s က', + s: 'စက္ကန်.အနည်းငယ်', + m: 'တစ်မိနစ်', + mm: '%d မိနစ်', + h: 'တစ်နာရီ', + hh: '%d နာရီ', + d: 'တစ်ရက်', + dd: '%d ရက်', + M: 'တစ်လ', + MM: '%d လ', + y: 'တစ်နှစ်', + yy: '%d နှစ်' + }, + preparse: function (string) { + return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) { + return my__numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return my__symbolMap[match]; + }); + }, + week: { + dow: 1, // Monday is the first day of the week. + doy: 4 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : norwegian bokmål (nb) + //! authors : Espen Hovlandsdal : https://github.com/rexxars + //! Sigurd Gartmann : https://github.com/sigurdga + + var nb = moment__default.defineLocale('nb', { + months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'), + weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), + weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'), + weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] HH:mm', + LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' + }, + calendar : { + sameDay: '[i dag kl.] LT', + nextDay: '[i morgen kl.] LT', + nextWeek: 'dddd [kl.] LT', + lastDay: '[i går kl.] LT', + lastWeek: '[forrige] dddd [kl.] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'om %s', + past : 'for %s siden', + s : 'noen sekunder', + m : 'ett minutt', + mm : '%d minutter', + h : 'en time', + hh : '%d timer', + d : 'en dag', + dd : '%d dager', + M : 'en måned', + MM : '%d måneder', + y : 'ett år', + yy : '%d år' + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : nepali/nepalese + //! author : suvash : https://github.com/suvash + + var ne__symbolMap = { + '1': '१', + '2': '२', + '3': '३', + '4': '४', + '5': '५', + '6': '६', + '7': '७', + '8': '८', + '9': '९', + '0': '०' + }, + ne__numberMap = { + '१': '1', + '२': '2', + '३': '3', + '४': '4', + '५': '5', + '६': '6', + '७': '7', + '८': '8', + '९': '9', + '०': '0' + }; + + var ne = moment__default.defineLocale('ne', { + months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'), + monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'), + weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'), + weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'), + weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'), + longDateFormat : { + LT : 'Aको h:mm बजे', + LTS : 'Aको h:mm:ss बजे', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, Aको h:mm बजे', + LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे' + }, + preparse: function (string) { + return string.replace(/[१२३४५६७८९०]/g, function (match) { + return ne__numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return ne__symbolMap[match]; + }); + }, + meridiemParse: /राति|बिहान|दिउँसो|साँझ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'राति') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'बिहान') { + return hour; + } else if (meridiem === 'दिउँसो') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'साँझ') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 3) { + return 'राति'; + } else if (hour < 12) { + return 'बिहान'; + } else if (hour < 16) { + return 'दिउँसो'; + } else if (hour < 20) { + return 'साँझ'; + } else { + return 'राति'; + } + }, + calendar : { + sameDay : '[आज] LT', + nextDay : '[भोलि] LT', + nextWeek : '[आउँदो] dddd[,] LT', + lastDay : '[हिजो] LT', + lastWeek : '[गएको] dddd[,] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%sमा', + past : '%s अगाडि', + s : 'केही क्षण', + m : 'एक मिनेट', + mm : '%d मिनेट', + h : 'एक घण्टा', + hh : '%d घण्टा', + d : 'एक दिन', + dd : '%d दिन', + M : 'एक महिना', + MM : '%d महिना', + y : 'एक बर्ष', + yy : '%d बर्ष' + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : dutch (nl) + //! author : Joris Röling : https://github.com/jjupiter + + var nl__monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), + nl__monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); + + var nl = moment__default.defineLocale('nl', { + months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), + monthsShort : function (m, format) { + if (/-MMM-/.test(format)) { + return nl__monthsShortWithoutDots[m.month()]; + } else { + return nl__monthsShortWithDots[m.month()]; + } + }, + weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), + weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), + weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD-MM-YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[vandaag om] LT', + nextDay: '[morgen om] LT', + nextWeek: 'dddd [om] LT', + lastDay: '[gisteren om] LT', + lastWeek: '[afgelopen] dddd [om] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'over %s', + past : '%s geleden', + s : 'een paar seconden', + m : 'één minuut', + mm : '%d minuten', + h : 'één uur', + hh : '%d uur', + d : 'één dag', + dd : '%d dagen', + M : 'één maand', + MM : '%d maanden', + y : 'één jaar', + yy : '%d jaar' + }, + ordinalParse: /\d{1,2}(ste|de)/, + ordinal : function (number) { + return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : norwegian nynorsk (nn) + //! author : https://github.com/mechuwind + + var nn = moment__default.defineLocale('nn', { + months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), + monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), + weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'), + weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'), + weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY [kl.] H:mm', + LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' + }, + calendar : { + sameDay: '[I dag klokka] LT', + nextDay: '[I morgon klokka] LT', + nextWeek: 'dddd [klokka] LT', + lastDay: '[I går klokka] LT', + lastWeek: '[Føregåande] dddd [klokka] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'om %s', + past : 'for %s sidan', + s : 'nokre sekund', + m : 'eit minutt', + mm : '%d minutt', + h : 'ein time', + hh : '%d timar', + d : 'ein dag', + dd : '%d dagar', + M : 'ein månad', + MM : '%d månader', + y : 'eit år', + yy : '%d år' + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : punjabi india (pa-in) + //! author : Harpreet Singh : https://github.com/harpreetkhalsagtbit + + var pa_in__symbolMap = { + '1': '੧', + '2': '੨', + '3': '੩', + '4': '੪', + '5': '੫', + '6': '੬', + '7': '੭', + '8': '੮', + '9': '੯', + '0': '੦' + }, + pa_in__numberMap = { + '੧': '1', + '੨': '2', + '੩': '3', + '੪': '4', + '੫': '5', + '੬': '6', + '੭': '7', + '੮': '8', + '੯': '9', + '੦': '0' + }; + + var pa_in = moment__default.defineLocale('pa-in', { + // There are months name as per Nanakshahi Calender but they are not used as rigidly in modern Punjabi. + months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'), + monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'), + weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'), + weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), + weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), + longDateFormat : { + LT : 'A h:mm ਵਜੇ', + LTS : 'A h:mm:ss ਵਜੇ', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm ਵਜੇ', + LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ' + }, + calendar : { + sameDay : '[ਅਜ] LT', + nextDay : '[ਕਲ] LT', + nextWeek : 'dddd, LT', + lastDay : '[ਕਲ] LT', + lastWeek : '[ਪਿਛਲੇ] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s ਵਿੱਚ', + past : '%s ਪਿਛਲੇ', + s : 'ਕੁਝ ਸਕਿੰਟ', + m : 'ਇਕ ਮਿੰਟ', + mm : '%d ਮਿੰਟ', + h : 'ਇੱਕ ਘੰਟਾ', + hh : '%d ਘੰਟੇ', + d : 'ਇੱਕ ਦਿਨ', + dd : '%d ਦਿਨ', + M : 'ਇੱਕ ਮਹੀਨਾ', + MM : '%d ਮਹੀਨੇ', + y : 'ਇੱਕ ਸਾਲ', + yy : '%d ਸਾਲ' + }, + preparse: function (string) { + return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) { + return pa_in__numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return pa_in__symbolMap[match]; + }); + }, + // Punjabi notation for meridiems are quite fuzzy in practice. While there exists + // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi. + meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'ਰਾਤ') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ਸਵੇਰ') { + return hour; + } else if (meridiem === 'ਦੁਪਹਿਰ') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'ਸ਼ਾਮ') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ਰਾਤ'; + } else if (hour < 10) { + return 'ਸਵੇਰ'; + } else if (hour < 17) { + return 'ਦੁਪਹਿਰ'; + } else if (hour < 20) { + return 'ਸ਼ਾਮ'; + } else { + return 'ਰਾਤ'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : polish (pl) + //! author : Rafal Hirsz : https://github.com/evoL + + var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'), + monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_'); + function pl__plural(n) { + return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1); + } + function pl__translate(number, withoutSuffix, key) { + var result = number + ' '; + switch (key) { + case 'm': + return withoutSuffix ? 'minuta' : 'minutę'; + case 'mm': + return result + (pl__plural(number) ? 'minuty' : 'minut'); + case 'h': + return withoutSuffix ? 'godzina' : 'godzinę'; + case 'hh': + return result + (pl__plural(number) ? 'godziny' : 'godzin'); + case 'MM': + return result + (pl__plural(number) ? 'miesiące' : 'miesięcy'); + case 'yy': + return result + (pl__plural(number) ? 'lata' : 'lat'); + } + } + + var pl = moment__default.defineLocale('pl', { + months : function (momentToFormat, format) { + if (format === '') { + // Hack: if format empty we know this is used to generate + // RegExp by moment. Give then back both valid forms of months + // in RegExp ready format. + return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')'; + } else if (/D MMMM/.test(format)) { + return monthsSubjective[momentToFormat.month()]; + } else { + return monthsNominative[momentToFormat.month()]; + } + }, + monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'), + weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'), + weekdaysShort : 'nie_pon_wt_śr_czw_pt_sb'.split('_'), + weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Dziś o] LT', + nextDay: '[Jutro o] LT', + nextWeek: '[W] dddd [o] LT', + lastDay: '[Wczoraj o] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[W zeszłą niedzielę o] LT'; + case 3: + return '[W zeszłą środę o] LT'; + case 6: + return '[W zeszłą sobotę o] LT'; + default: + return '[W zeszły] dddd [o] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'za %s', + past : '%s temu', + s : 'kilka sekund', + m : pl__translate, + mm : pl__translate, + h : pl__translate, + hh : pl__translate, + d : '1 dzień', + dd : '%d dni', + M : 'miesiąc', + MM : pl__translate, + y : 'rok', + yy : pl__translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : brazilian portuguese (pt-br) + //! author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira + + var pt_br = moment__default.defineLocale('pt-br', { + months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'), + monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), + weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'), + weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), + weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY [às] HH:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm' + }, + calendar : { + sameDay: '[Hoje às] LT', + nextDay: '[Amanhã às] LT', + nextWeek: 'dddd [às] LT', + lastDay: '[Ontem às] LT', + lastWeek: function () { + return (this.day() === 0 || this.day() === 6) ? + '[Último] dddd [às] LT' : // Saturday + Sunday + '[Última] dddd [às] LT'; // Monday - Friday + }, + sameElse: 'L' + }, + relativeTime : { + future : 'em %s', + past : '%s atrás', + s : 'poucos segundos', + m : 'um minuto', + mm : '%d minutos', + h : 'uma hora', + hh : '%d horas', + d : 'um dia', + dd : '%d dias', + M : 'um mês', + MM : '%d meses', + y : 'um ano', + yy : '%d anos' + }, + ordinalParse: /\d{1,2}º/, + ordinal : '%dº' + }); + + //! moment.js locale configuration + //! locale : portuguese (pt) + //! author : Jefferson : https://github.com/jalex79 + + var pt = moment__default.defineLocale('pt', { + months : 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'), + monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), + weekdays : 'Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado'.split('_'), + weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), + weekdaysMin : 'Dom_2ª_3ª_4ª_5ª_6ª_Sáb'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D [de] MMMM [de] YYYY', + LLL : 'D [de] MMMM [de] YYYY HH:mm', + LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm' + }, + calendar : { + sameDay: '[Hoje às] LT', + nextDay: '[Amanhã às] LT', + nextWeek: 'dddd [às] LT', + lastDay: '[Ontem às] LT', + lastWeek: function () { + return (this.day() === 0 || this.day() === 6) ? + '[Último] dddd [às] LT' : // Saturday + Sunday + '[Última] dddd [às] LT'; // Monday - Friday + }, + sameElse: 'L' + }, + relativeTime : { + future : 'em %s', + past : 'há %s', + s : 'segundos', + m : 'um minuto', + mm : '%d minutos', + h : 'uma hora', + hh : '%d horas', + d : 'um dia', + dd : '%d dias', + M : 'um mês', + MM : '%d meses', + y : 'um ano', + yy : '%d anos' + }, + ordinalParse: /\d{1,2}º/, + ordinal : '%dº', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : romanian (ro) + //! author : Vlad Gurdiga : https://github.com/gurdiga + //! author : Valentin Agachi : https://github.com/avaly + + function ro__relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'mm': 'minute', + 'hh': 'ore', + 'dd': 'zile', + 'MM': 'luni', + 'yy': 'ani' + }, + separator = ' '; + if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) { + separator = ' de '; + } + return number + separator + format[key]; + } + + var ro = moment__default.defineLocale('ro', { + months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'), + monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'), + weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'), + weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'), + weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY H:mm', + LLLL : 'dddd, D MMMM YYYY H:mm' + }, + calendar : { + sameDay: '[azi la] LT', + nextDay: '[mâine la] LT', + nextWeek: 'dddd [la] LT', + lastDay: '[ieri la] LT', + lastWeek: '[fosta] dddd [la] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'peste %s', + past : '%s în urmă', + s : 'câteva secunde', + m : 'un minut', + mm : ro__relativeTimeWithPlural, + h : 'o oră', + hh : ro__relativeTimeWithPlural, + d : 'o zi', + dd : ro__relativeTimeWithPlural, + M : 'o lună', + MM : ro__relativeTimeWithPlural, + y : 'un an', + yy : ro__relativeTimeWithPlural + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : russian (ru) + //! author : Viktorminator : https://github.com/Viktorminator + //! Author : Menelion Elensúle : https://github.com/Oire + //! author : Коренберг Марк : https://github.com/socketpair + + function ru__plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); + } + function ru__relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут', + 'hh': 'час_часа_часов', + 'dd': 'день_дня_дней', + 'MM': 'месяц_месяца_месяцев', + 'yy': 'год_года_лет' + }; + if (key === 'm') { + return withoutSuffix ? 'минута' : 'минуту'; + } + else { + return number + ' ' + ru__plural(format[key], +number); + } + } + var monthsParse = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i]; + + // http://new.gramota.ru/spravka/rules/139-prop : § 103 + var ru = moment__default.defineLocale('ru', { + months : { + format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'), + standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_') + }, + monthsShort : { + format: 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_'), + standalone: 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_') + }, + weekdays : { + standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'), + format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'), + isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/ + }, + weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), + weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), + monthsParse : monthsParse, + longMonthsParse : monthsParse, + shortMonthsParse : monthsParse, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY г.', + LLL : 'D MMMM YYYY г., HH:mm', + LLLL : 'dddd, D MMMM YYYY г., HH:mm' + }, + calendar : { + sameDay: '[Сегодня в] LT', + nextDay: '[Завтра в] LT', + lastDay: '[Вчера в] LT', + nextWeek: function (now) { + if (now.week() !== this.week()) { + switch (this.day()) { + case 0: + return '[В следующее] dddd [в] LT'; + case 1: + case 2: + case 4: + return '[В следующий] dddd [в] LT'; + case 3: + case 5: + case 6: + return '[В следующую] dddd [в] LT'; + } + } else { + if (this.day() === 2) { + return '[Во] dddd [в] LT'; + } else { + return '[В] dddd [в] LT'; + } + } + }, + lastWeek: function (now) { + if (now.week() !== this.week()) { + switch (this.day()) { + case 0: + return '[В прошлое] dddd [в] LT'; + case 1: + case 2: + case 4: + return '[В прошлый] dddd [в] LT'; + case 3: + case 5: + case 6: + return '[В прошлую] dddd [в] LT'; + } + } else { + if (this.day() === 2) { + return '[Во] dddd [в] LT'; + } else { + return '[В] dddd [в] LT'; + } + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'через %s', + past : '%s назад', + s : 'несколько секунд', + m : ru__relativeTimeWithPlural, + mm : ru__relativeTimeWithPlural, + h : 'час', + hh : ru__relativeTimeWithPlural, + d : 'день', + dd : ru__relativeTimeWithPlural, + M : 'месяц', + MM : ru__relativeTimeWithPlural, + y : 'год', + yy : ru__relativeTimeWithPlural + }, + meridiemParse: /ночи|утра|дня|вечера/i, + isPM : function (input) { + return /^(дня|вечера)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ночи'; + } else if (hour < 12) { + return 'утра'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечера'; + } + }, + ordinalParse: /\d{1,2}-(й|го|я)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + return number + '-й'; + case 'D': + return number + '-го'; + case 'w': + case 'W': + return number + '-я'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Northern Sami (se) + //! authors : Bård Rolstad Henriksen : https://github.com/karamell + + + var se = moment__default.defineLocale('se', { + months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'), + monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'), + weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'), + weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'), + weekdaysMin : 's_v_m_g_d_b_L'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'MMMM D. [b.] YYYY', + LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm', + LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm' + }, + calendar : { + sameDay: '[otne ti] LT', + nextDay: '[ihttin ti] LT', + nextWeek: 'dddd [ti] LT', + lastDay: '[ikte ti] LT', + lastWeek: '[ovddit] dddd [ti] LT', + sameElse: 'L' + }, + relativeTime : { + future : '%s geažes', + past : 'maŋit %s', + s : 'moadde sekunddat', + m : 'okta minuhta', + mm : '%d minuhtat', + h : 'okta diimmu', + hh : '%d diimmut', + d : 'okta beaivi', + dd : '%d beaivvit', + M : 'okta mánnu', + MM : '%d mánut', + y : 'okta jahki', + yy : '%d jagit' + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Sinhalese (si) + //! author : Sampath Sitinamaluwa : https://github.com/sampathsris + + /*jshint -W100*/ + var si = moment__default.defineLocale('si', { + months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'), + monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'), + weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'), + weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'), + weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'), + longDateFormat : { + LT : 'a h:mm', + LTS : 'a h:mm:ss', + L : 'YYYY/MM/DD', + LL : 'YYYY MMMM D', + LLL : 'YYYY MMMM D, a h:mm', + LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss' + }, + calendar : { + sameDay : '[අද] LT[ට]', + nextDay : '[හෙට] LT[ට]', + nextWeek : 'dddd LT[ට]', + lastDay : '[ඊයේ] LT[ට]', + lastWeek : '[පසුගිය] dddd LT[ට]', + sameElse : 'L' + }, + relativeTime : { + future : '%sකින්', + past : '%sකට පෙර', + s : 'තත්පර කිහිපය', + m : 'මිනිත්තුව', + mm : 'මිනිත්තු %d', + h : 'පැය', + hh : 'පැය %d', + d : 'දිනය', + dd : 'දින %d', + M : 'මාසය', + MM : 'මාස %d', + y : 'වසර', + yy : 'වසර %d' + }, + ordinalParse: /\d{1,2} වැනි/, + ordinal : function (number) { + return number + ' වැනි'; + }, + meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./, + isPM : function (input) { + return input === 'ප.ව.' || input === 'පස් වරු'; + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'ප.ව.' : 'පස් වරු'; + } else { + return isLower ? 'පෙ.ව.' : 'පෙර වරු'; + } + } + }); + + //! moment.js locale configuration + //! locale : slovak (sk) + //! author : Martin Minka : https://github.com/k2s + //! based on work of petrbela : https://github.com/petrbela + + var sk__months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'), + sk__monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_'); + function sk__plural(n) { + return (n > 1) && (n < 5); + } + function sk__translate(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami'; + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou'); + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (withoutSuffix || isFuture) { + return result + (sk__plural(number) ? 'minúty' : 'minút'); + } else { + return result + 'minútami'; + } + break; + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (withoutSuffix || isFuture) { + return result + (sk__plural(number) ? 'hodiny' : 'hodín'); + } else { + return result + 'hodinami'; + } + break; + case 'd': // a day / in a day / a day ago + return (withoutSuffix || isFuture) ? 'deň' : 'dňom'; + case 'dd': // 9 days / in 9 days / 9 days ago + if (withoutSuffix || isFuture) { + return result + (sk__plural(number) ? 'dni' : 'dní'); + } else { + return result + 'dňami'; + } + break; + case 'M': // a month / in a month / a month ago + return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom'; + case 'MM': // 9 months / in 9 months / 9 months ago + if (withoutSuffix || isFuture) { + return result + (sk__plural(number) ? 'mesiace' : 'mesiacov'); + } else { + return result + 'mesiacmi'; + } + break; + case 'y': // a year / in a year / a year ago + return (withoutSuffix || isFuture) ? 'rok' : 'rokom'; + case 'yy': // 9 years / in 9 years / 9 years ago + if (withoutSuffix || isFuture) { + return result + (sk__plural(number) ? 'roky' : 'rokov'); + } else { + return result + 'rokmi'; + } + break; + } + } + + var sk = moment__default.defineLocale('sk', { + months : sk__months, + monthsShort : sk__monthsShort, + weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'), + weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'), + weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'), + longDateFormat : { + LT: 'H:mm', + LTS : 'H:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd D. MMMM YYYY H:mm' + }, + calendar : { + sameDay: '[dnes o] LT', + nextDay: '[zajtra o] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[v nedeľu o] LT'; + case 1: + case 2: + return '[v] dddd [o] LT'; + case 3: + return '[v stredu o] LT'; + case 4: + return '[vo štvrtok o] LT'; + case 5: + return '[v piatok o] LT'; + case 6: + return '[v sobotu o] LT'; + } + }, + lastDay: '[včera o] LT', + lastWeek: function () { + switch (this.day()) { + case 0: + return '[minulú nedeľu o] LT'; + case 1: + case 2: + return '[minulý] dddd [o] LT'; + case 3: + return '[minulú stredu o] LT'; + case 4: + case 5: + return '[minulý] dddd [o] LT'; + case 6: + return '[minulú sobotu o] LT'; + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'za %s', + past : 'pred %s', + s : sk__translate, + m : sk__translate, + mm : sk__translate, + h : sk__translate, + hh : sk__translate, + d : sk__translate, + dd : sk__translate, + M : sk__translate, + MM : sk__translate, + y : sk__translate, + yy : sk__translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : slovenian (sl) + //! author : Robert Sedovšek : https://github.com/sedovsek + + function sl__processRelativeTime(number, withoutSuffix, key, isFuture) { + var result = number + ' '; + switch (key) { + case 's': + return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami'; + case 'm': + return withoutSuffix ? 'ena minuta' : 'eno minuto'; + case 'mm': + if (number === 1) { + result += withoutSuffix ? 'minuta' : 'minuto'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'minuti' : 'minutama'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'minute' : 'minutami'; + } else { + result += withoutSuffix || isFuture ? 'minut' : 'minutami'; + } + return result; + case 'h': + return withoutSuffix ? 'ena ura' : 'eno uro'; + case 'hh': + if (number === 1) { + result += withoutSuffix ? 'ura' : 'uro'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'uri' : 'urama'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'ure' : 'urami'; + } else { + result += withoutSuffix || isFuture ? 'ur' : 'urami'; + } + return result; + case 'd': + return withoutSuffix || isFuture ? 'en dan' : 'enim dnem'; + case 'dd': + if (number === 1) { + result += withoutSuffix || isFuture ? 'dan' : 'dnem'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'dni' : 'dnevoma'; + } else { + result += withoutSuffix || isFuture ? 'dni' : 'dnevi'; + } + return result; + case 'M': + return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem'; + case 'MM': + if (number === 1) { + result += withoutSuffix || isFuture ? 'mesec' : 'mesecem'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'meseca' : 'mesecema'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'mesece' : 'meseci'; + } else { + result += withoutSuffix || isFuture ? 'mesecev' : 'meseci'; + } + return result; + case 'y': + return withoutSuffix || isFuture ? 'eno leto' : 'enim letom'; + case 'yy': + if (number === 1) { + result += withoutSuffix || isFuture ? 'leto' : 'letom'; + } else if (number === 2) { + result += withoutSuffix || isFuture ? 'leti' : 'letoma'; + } else if (number < 5) { + result += withoutSuffix || isFuture ? 'leta' : 'leti'; + } else { + result += withoutSuffix || isFuture ? 'let' : 'leti'; + } + return result; + } + } + + var sl = moment__default.defineLocale('sl', { + months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'), + monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'), + weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'), + weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'), + weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'), + longDateFormat : { + LT : 'H:mm', + LTS : 'H:mm:ss', + L : 'DD. MM. YYYY', + LL : 'D. MMMM YYYY', + LLL : 'D. MMMM YYYY H:mm', + LLLL : 'dddd, D. MMMM YYYY H:mm' + }, + calendar : { + sameDay : '[danes ob] LT', + nextDay : '[jutri ob] LT', + + nextWeek : function () { + switch (this.day()) { + case 0: + return '[v] [nedeljo] [ob] LT'; + case 3: + return '[v] [sredo] [ob] LT'; + case 6: + return '[v] [soboto] [ob] LT'; + case 1: + case 2: + case 4: + case 5: + return '[v] dddd [ob] LT'; + } + }, + lastDay : '[včeraj ob] LT', + lastWeek : function () { + switch (this.day()) { + case 0: + return '[prejšnjo] [nedeljo] [ob] LT'; + case 3: + return '[prejšnjo] [sredo] [ob] LT'; + case 6: + return '[prejšnjo] [soboto] [ob] LT'; + case 1: + case 2: + case 4: + case 5: + return '[prejšnji] dddd [ob] LT'; + } + }, + sameElse : 'L' + }, + relativeTime : { + future : 'čez %s', + past : 'pred %s', + s : sl__processRelativeTime, + m : sl__processRelativeTime, + mm : sl__processRelativeTime, + h : sl__processRelativeTime, + hh : sl__processRelativeTime, + d : sl__processRelativeTime, + dd : sl__processRelativeTime, + M : sl__processRelativeTime, + MM : sl__processRelativeTime, + y : sl__processRelativeTime, + yy : sl__processRelativeTime + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Albanian (sq) + //! author : Flakërim Ismani : https://github.com/flakerimi + //! author: Menelion Elensúle: https://github.com/Oire (tests) + //! author : Oerd Cukalla : https://github.com/oerd (fixes) + + var sq = moment__default.defineLocale('sq', { + months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'), + monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'), + weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'), + weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'), + weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'), + meridiemParse: /PD|MD/, + isPM: function (input) { + return input.charAt(0) === 'M'; + }, + meridiem : function (hours, minutes, isLower) { + return hours < 12 ? 'PD' : 'MD'; + }, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[Sot në] LT', + nextDay : '[Nesër në] LT', + nextWeek : 'dddd [në] LT', + lastDay : '[Dje në] LT', + lastWeek : 'dddd [e kaluar në] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'në %s', + past : '%s më parë', + s : 'disa sekonda', + m : 'një minutë', + mm : '%d minuta', + h : 'një orë', + hh : '%d orë', + d : 'një ditë', + dd : '%d ditë', + M : 'një muaj', + MM : '%d muaj', + y : 'një vit', + yy : '%d vite' + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Serbian-cyrillic (sr-cyrl) + //! author : Milan Janačković : https://github.com/milan-j + + var sr_cyrl__translator = { + words: { //Different grammatical cases + m: ['један минут', 'једне минуте'], + mm: ['минут', 'минуте', 'минута'], + h: ['један сат', 'једног сата'], + hh: ['сат', 'сата', 'сати'], + dd: ['дан', 'дана', 'дана'], + MM: ['месец', 'месеца', 'месеци'], + yy: ['година', 'године', 'година'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = sr_cyrl__translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + sr_cyrl__translator.correctGrammaticalCase(number, wordKey); + } + } + }; + + var sr_cyrl = moment__default.defineLocale('sr-cyrl', { + months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'], + monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'], + weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'], + weekdaysShort: ['нед.', 'пон.', 'уто.', 'сре.', 'чет.', 'пет.', 'суб.'], + weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'], + longDateFormat: { + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD. MM. YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' + }, + calendar: { + sameDay: '[данас у] LT', + nextDay: '[сутра у] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[у] [недељу] [у] LT'; + case 3: + return '[у] [среду] [у] LT'; + case 6: + return '[у] [суботу] [у] LT'; + case 1: + case 2: + case 4: + case 5: + return '[у] dddd [у] LT'; + } + }, + lastDay : '[јуче у] LT', + lastWeek : function () { + var lastWeekDays = [ + '[прошле] [недеље] [у] LT', + '[прошлог] [понедељка] [у] LT', + '[прошлог] [уторка] [у] LT', + '[прошле] [среде] [у] LT', + '[прошлог] [четвртка] [у] LT', + '[прошлог] [петка] [у] LT', + '[прошле] [суботе] [у] LT' + ]; + return lastWeekDays[this.day()]; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'за %s', + past : 'пре %s', + s : 'неколико секунди', + m : sr_cyrl__translator.translate, + mm : sr_cyrl__translator.translate, + h : sr_cyrl__translator.translate, + hh : sr_cyrl__translator.translate, + d : 'дан', + dd : sr_cyrl__translator.translate, + M : 'месец', + MM : sr_cyrl__translator.translate, + y : 'годину', + yy : sr_cyrl__translator.translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Serbian-latin (sr) + //! author : Milan Janačković : https://github.com/milan-j + + var sr__translator = { + words: { //Different grammatical cases + m: ['jedan minut', 'jedne minute'], + mm: ['minut', 'minute', 'minuta'], + h: ['jedan sat', 'jednog sata'], + hh: ['sat', 'sata', 'sati'], + dd: ['dan', 'dana', 'dana'], + MM: ['mesec', 'meseca', 'meseci'], + yy: ['godina', 'godine', 'godina'] + }, + correctGrammaticalCase: function (number, wordKey) { + return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); + }, + translate: function (number, withoutSuffix, key) { + var wordKey = sr__translator.words[key]; + if (key.length === 1) { + return withoutSuffix ? wordKey[0] : wordKey[1]; + } else { + return number + ' ' + sr__translator.correctGrammaticalCase(number, wordKey); + } + } + }; + + var sr = moment__default.defineLocale('sr', { + months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'], + monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'], + weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'], + weekdaysShort: ['ned.', 'pon.', 'uto.', 'sre.', 'čet.', 'pet.', 'sub.'], + weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'], + longDateFormat: { + LT: 'H:mm', + LTS : 'H:mm:ss', + L: 'DD. MM. YYYY', + LL: 'D. MMMM YYYY', + LLL: 'D. MMMM YYYY H:mm', + LLLL: 'dddd, D. MMMM YYYY H:mm' + }, + calendar: { + sameDay: '[danas u] LT', + nextDay: '[sutra u] LT', + nextWeek: function () { + switch (this.day()) { + case 0: + return '[u] [nedelju] [u] LT'; + case 3: + return '[u] [sredu] [u] LT'; + case 6: + return '[u] [subotu] [u] LT'; + case 1: + case 2: + case 4: + case 5: + return '[u] dddd [u] LT'; + } + }, + lastDay : '[juče u] LT', + lastWeek : function () { + var lastWeekDays = [ + '[prošle] [nedelje] [u] LT', + '[prošlog] [ponedeljka] [u] LT', + '[prošlog] [utorka] [u] LT', + '[prošle] [srede] [u] LT', + '[prošlog] [četvrtka] [u] LT', + '[prošlog] [petka] [u] LT', + '[prošle] [subote] [u] LT' + ]; + return lastWeekDays[this.day()]; + }, + sameElse : 'L' + }, + relativeTime : { + future : 'za %s', + past : 'pre %s', + s : 'nekoliko sekundi', + m : sr__translator.translate, + mm : sr__translator.translate, + h : sr__translator.translate, + hh : sr__translator.translate, + d : 'dan', + dd : sr__translator.translate, + M : 'mesec', + MM : sr__translator.translate, + y : 'godinu', + yy : sr__translator.translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : swedish (sv) + //! author : Jens Alm : https://github.com/ulmus + + var sv = moment__default.defineLocale('sv', { + months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'), + monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), + weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'), + weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'), + weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'YYYY-MM-DD', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Idag] LT', + nextDay: '[Imorgon] LT', + lastDay: '[Igår] LT', + nextWeek: '[På] dddd LT', + lastWeek: '[I] dddd[s] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'om %s', + past : 'för %s sedan', + s : 'några sekunder', + m : 'en minut', + mm : '%d minuter', + h : 'en timme', + hh : '%d timmar', + d : 'en dag', + dd : '%d dagar', + M : 'en månad', + MM : '%d månader', + y : 'ett år', + yy : '%d år' + }, + ordinalParse: /\d{1,2}(e|a)/, + ordinal : function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'e' : + (b === 1) ? 'a' : + (b === 2) ? 'a' : + (b === 3) ? 'e' : 'e'; + return number + output; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : swahili (sw) + //! author : Fahad Kassim : https://github.com/fadsel + + var sw = moment__default.defineLocale('sw', { + months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'), + monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'), + weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'), + weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'), + weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[leo saa] LT', + nextDay : '[kesho saa] LT', + nextWeek : '[wiki ijayo] dddd [saat] LT', + lastDay : '[jana] LT', + lastWeek : '[wiki iliyopita] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s baadaye', + past : 'tokea %s', + s : 'hivi punde', + m : 'dakika moja', + mm : 'dakika %d', + h : 'saa limoja', + hh : 'masaa %d', + d : 'siku moja', + dd : 'masiku %d', + M : 'mwezi mmoja', + MM : 'miezi %d', + y : 'mwaka mmoja', + yy : 'miaka %d' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : tamil (ta) + //! author : Arjunkumar Krishnamoorthy : https://github.com/tk120404 + + var ta__symbolMap = { + '1': '௧', + '2': '௨', + '3': '௩', + '4': '௪', + '5': '௫', + '6': '௬', + '7': '௭', + '8': '௮', + '9': '௯', + '0': '௦' + }, ta__numberMap = { + '௧': '1', + '௨': '2', + '௩': '3', + '௪': '4', + '௫': '5', + '௬': '6', + '௭': '7', + '௮': '8', + '௯': '9', + '௦': '0' + }; + + var ta = moment__default.defineLocale('ta', { + months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), + monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), + weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'), + weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'), + weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, HH:mm', + LLLL : 'dddd, D MMMM YYYY, HH:mm' + }, + calendar : { + sameDay : '[இன்று] LT', + nextDay : '[நாளை] LT', + nextWeek : 'dddd, LT', + lastDay : '[நேற்று] LT', + lastWeek : '[கடந்த வாரம்] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s இல்', + past : '%s முன்', + s : 'ஒரு சில விநாடிகள்', + m : 'ஒரு நிமிடம்', + mm : '%d நிமிடங்கள்', + h : 'ஒரு மணி நேரம்', + hh : '%d மணி நேரம்', + d : 'ஒரு நாள்', + dd : '%d நாட்கள்', + M : 'ஒரு மாதம்', + MM : '%d மாதங்கள்', + y : 'ஒரு வருடம்', + yy : '%d ஆண்டுகள்' + }, + ordinalParse: /\d{1,2}வது/, + ordinal : function (number) { + return number + 'வது'; + }, + preparse: function (string) { + return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) { + return ta__numberMap[match]; + }); + }, + postformat: function (string) { + return string.replace(/\d/g, function (match) { + return ta__symbolMap[match]; + }); + }, + // refer http://ta.wikipedia.org/s/1er1 + meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/, + meridiem : function (hour, minute, isLower) { + if (hour < 2) { + return ' யாமம்'; + } else if (hour < 6) { + return ' வைகறை'; // வைகறை + } else if (hour < 10) { + return ' காலை'; // காலை + } else if (hour < 14) { + return ' நண்பகல்'; // நண்பகல் + } else if (hour < 18) { + return ' எற்பாடு'; // எற்பாடு + } else if (hour < 22) { + return ' மாலை'; // மாலை + } else { + return ' யாமம்'; + } + }, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'யாமம்') { + return hour < 2 ? hour : hour + 12; + } else if (meridiem === 'வைகறை' || meridiem === 'காலை') { + return hour; + } else if (meridiem === 'நண்பகல்') { + return hour >= 10 ? hour : hour + 12; + } else { + return hour + 12; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : telugu (te) + //! author : Krishna Chaitanya Thota : https://github.com/kcthota + + var te = moment__default.defineLocale('te', { + months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'), + monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'), + weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'), + weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'), + weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'), + longDateFormat : { + LT : 'A h:mm', + LTS : 'A h:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY, A h:mm', + LLLL : 'dddd, D MMMM YYYY, A h:mm' + }, + calendar : { + sameDay : '[నేడు] LT', + nextDay : '[రేపు] LT', + nextWeek : 'dddd, LT', + lastDay : '[నిన్న] LT', + lastWeek : '[గత] dddd, LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s లో', + past : '%s క్రితం', + s : 'కొన్ని క్షణాలు', + m : 'ఒక నిమిషం', + mm : '%d నిమిషాలు', + h : 'ఒక గంట', + hh : '%d గంటలు', + d : 'ఒక రోజు', + dd : '%d రోజులు', + M : 'ఒక నెల', + MM : '%d నెలలు', + y : 'ఒక సంవత్సరం', + yy : '%d సంవత్సరాలు' + }, + ordinalParse : /\d{1,2}వ/, + ordinal : '%dవ', + meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === 'రాత్రి') { + return hour < 4 ? hour : hour + 12; + } else if (meridiem === 'ఉదయం') { + return hour; + } else if (meridiem === 'మధ్యాహ్నం') { + return hour >= 10 ? hour : hour + 12; + } else if (meridiem === 'సాయంత్రం') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'రాత్రి'; + } else if (hour < 10) { + return 'ఉదయం'; + } else if (hour < 17) { + return 'మధ్యాహ్నం'; + } else if (hour < 20) { + return 'సాయంత్రం'; + } else { + return 'రాత్రి'; + } + }, + week : { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : thai (th) + //! author : Kridsada Thanabulpong : https://github.com/sirn + + var th = moment__default.defineLocale('th', { + months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'), + monthsShort : 'มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา'.split('_'), + weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'), + weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference + weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'), + longDateFormat : { + LT : 'H นาฬิกา m นาที', + LTS : 'H นาฬิกา m นาที s วินาที', + L : 'YYYY/MM/DD', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY เวลา H นาฬิกา m นาที', + LLLL : 'วันddddที่ D MMMM YYYY เวลา H นาฬิกา m นาที' + }, + meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/, + isPM: function (input) { + return input === 'หลังเที่ยง'; + }, + meridiem : function (hour, minute, isLower) { + if (hour < 12) { + return 'ก่อนเที่ยง'; + } else { + return 'หลังเที่ยง'; + } + }, + calendar : { + sameDay : '[วันนี้ เวลา] LT', + nextDay : '[พรุ่งนี้ เวลา] LT', + nextWeek : 'dddd[หน้า เวลา] LT', + lastDay : '[เมื่อวานนี้ เวลา] LT', + lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'อีก %s', + past : '%sที่แล้ว', + s : 'ไม่กี่วินาที', + m : '1 นาที', + mm : '%d นาที', + h : '1 ชั่วโมง', + hh : '%d ชั่วโมง', + d : '1 วัน', + dd : '%d วัน', + M : '1 เดือน', + MM : '%d เดือน', + y : '1 ปี', + yy : '%d ปี' + } + }); + + //! moment.js locale configuration + //! locale : Tagalog/Filipino (tl-ph) + //! author : Dan Hagman + + var tl_ph = moment__default.defineLocale('tl-ph', { + months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'), + monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'), + weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'), + weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'), + weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'MM/D/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY HH:mm', + LLLL : 'dddd, MMMM DD, YYYY HH:mm' + }, + calendar : { + sameDay: '[Ngayon sa] LT', + nextDay: '[Bukas sa] LT', + nextWeek: 'dddd [sa] LT', + lastDay: '[Kahapon sa] LT', + lastWeek: 'dddd [huling linggo] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'sa loob ng %s', + past : '%s ang nakalipas', + s : 'ilang segundo', + m : 'isang minuto', + mm : '%d minuto', + h : 'isang oras', + hh : '%d oras', + d : 'isang araw', + dd : '%d araw', + M : 'isang buwan', + MM : '%d buwan', + y : 'isang taon', + yy : '%d taon' + }, + ordinalParse: /\d{1,2}/, + ordinal : function (number) { + return number; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Klingon (tlh) + //! author : Dominika Kruk : https://github.com/amaranthrose + + var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_'); + + function translateFuture(output) { + var time = output; + time = (output.indexOf('jaj') !== -1) ? + time.slice(0, -3) + 'leS' : + (output.indexOf('jar') !== -1) ? + time.slice(0, -3) + 'waQ' : + (output.indexOf('DIS') !== -1) ? + time.slice(0, -3) + 'nem' : + time + ' pIq'; + return time; + } + + function translatePast(output) { + var time = output; + time = (output.indexOf('jaj') !== -1) ? + time.slice(0, -3) + 'Hu’' : + (output.indexOf('jar') !== -1) ? + time.slice(0, -3) + 'wen' : + (output.indexOf('DIS') !== -1) ? + time.slice(0, -3) + 'ben' : + time + ' ret'; + return time; + } + + function tlh__translate(number, withoutSuffix, string, isFuture) { + var numberNoun = numberAsNoun(number); + switch (string) { + case 'mm': + return numberNoun + ' tup'; + case 'hh': + return numberNoun + ' rep'; + case 'dd': + return numberNoun + ' jaj'; + case 'MM': + return numberNoun + ' jar'; + case 'yy': + return numberNoun + ' DIS'; + } + } + + function numberAsNoun(number) { + var hundred = Math.floor((number % 1000) / 100), + ten = Math.floor((number % 100) / 10), + one = number % 10, + word = ''; + if (hundred > 0) { + word += numbersNouns[hundred] + 'vatlh'; + } + if (ten > 0) { + word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH'; + } + if (one > 0) { + word += ((word !== '') ? ' ' : '') + numbersNouns[one]; + } + return (word === '') ? 'pagh' : word; + } + + var tlh = moment__default.defineLocale('tlh', { + months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'), + monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'), + weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[DaHjaj] LT', + nextDay: '[wa’leS] LT', + nextWeek: 'LLL', + lastDay: '[wa’Hu’] LT', + lastWeek: 'LLL', + sameElse: 'L' + }, + relativeTime : { + future : translateFuture, + past : translatePast, + s : 'puS lup', + m : 'wa’ tup', + mm : tlh__translate, + h : 'wa’ rep', + hh : tlh__translate, + d : 'wa’ jaj', + dd : tlh__translate, + M : 'wa’ jar', + MM : tlh__translate, + y : 'wa’ DIS', + yy : tlh__translate + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : turkish (tr) + //! authors : Erhan Gundogan : https://github.com/erhangundogan, + //! Burak Yiğit Kaya: https://github.com/BYK + + var tr__suffixes = { + 1: '\'inci', + 5: '\'inci', + 8: '\'inci', + 70: '\'inci', + 80: '\'inci', + 2: '\'nci', + 7: '\'nci', + 20: '\'nci', + 50: '\'nci', + 3: '\'üncü', + 4: '\'üncü', + 100: '\'üncü', + 6: '\'ncı', + 9: '\'uncu', + 10: '\'uncu', + 30: '\'uncu', + 60: '\'ıncı', + 90: '\'ıncı' + }; + + var tr = moment__default.defineLocale('tr', { + months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'), + monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'), + weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'), + weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'), + weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd, D MMMM YYYY HH:mm' + }, + calendar : { + sameDay : '[bugün saat] LT', + nextDay : '[yarın saat] LT', + nextWeek : '[haftaya] dddd [saat] LT', + lastDay : '[dün] LT', + lastWeek : '[geçen hafta] dddd [saat] LT', + sameElse : 'L' + }, + relativeTime : { + future : '%s sonra', + past : '%s önce', + s : 'birkaç saniye', + m : 'bir dakika', + mm : '%d dakika', + h : 'bir saat', + hh : '%d saat', + d : 'bir gün', + dd : '%d gün', + M : 'bir ay', + MM : '%d ay', + y : 'bir yıl', + yy : '%d yıl' + }, + ordinalParse: /\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/, + ordinal : function (number) { + if (number === 0) { // special case for zero + return number + '\'ıncı'; + } + var a = number % 10, + b = number % 100 - a, + c = number >= 100 ? 100 : null; + return number + (tr__suffixes[a] || tr__suffixes[b] || tr__suffixes[c]); + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : talossan (tzl) + //! author : Robin van der Vliet : https://github.com/robin0van0der0v with the help of Iustì Canun + + + // After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals. + // This is currently too difficult (maybe even impossible) to add. + var tzl = moment__default.defineLocale('tzl', { + months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'), + monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'), + weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'), + weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'), + weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'), + longDateFormat : { + LT : 'HH.mm', + LTS : 'HH.mm.ss', + L : 'DD.MM.YYYY', + LL : 'D. MMMM [dallas] YYYY', + LLL : 'D. MMMM [dallas] YYYY HH.mm', + LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm' + }, + meridiemParse: /d\'o|d\'a/i, + isPM : function (input) { + return 'd\'o' === input.toLowerCase(); + }, + meridiem : function (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'd\'o' : 'D\'O'; + } else { + return isLower ? 'd\'a' : 'D\'A'; + } + }, + calendar : { + sameDay : '[oxhi à] LT', + nextDay : '[demà à] LT', + nextWeek : 'dddd [à] LT', + lastDay : '[ieiri à] LT', + lastWeek : '[sür el] dddd [lasteu à] LT', + sameElse : 'L' + }, + relativeTime : { + future : 'osprei %s', + past : 'ja%s', + s : tzl__processRelativeTime, + m : tzl__processRelativeTime, + mm : tzl__processRelativeTime, + h : tzl__processRelativeTime, + hh : tzl__processRelativeTime, + d : tzl__processRelativeTime, + dd : tzl__processRelativeTime, + M : tzl__processRelativeTime, + MM : tzl__processRelativeTime, + y : tzl__processRelativeTime, + yy : tzl__processRelativeTime + }, + ordinalParse: /\d{1,2}\./, + ordinal : '%d.', + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + function tzl__processRelativeTime(number, withoutSuffix, key, isFuture) { + var format = { + 's': ['viensas secunds', '\'iensas secunds'], + 'm': ['\'n míut', '\'iens míut'], + 'mm': [number + ' míuts', '' + number + ' míuts'], + 'h': ['\'n þora', '\'iensa þora'], + 'hh': [number + ' þoras', '' + number + ' þoras'], + 'd': ['\'n ziua', '\'iensa ziua'], + 'dd': [number + ' ziuas', '' + number + ' ziuas'], + 'M': ['\'n mes', '\'iens mes'], + 'MM': [number + ' mesen', '' + number + ' mesen'], + 'y': ['\'n ar', '\'iens ar'], + 'yy': [number + ' ars', '' + number + ' ars'] + }; + return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]); + } + + //! moment.js locale configuration + //! locale : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn) + //! author : Abdel Said : https://github.com/abdelsaid + + var tzm_latn = moment__default.defineLocale('tzm-latn', { + months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), + monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), + weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[asdkh g] LT', + nextDay: '[aska g] LT', + nextWeek: 'dddd [g] LT', + lastDay: '[assant g] LT', + lastWeek: 'dddd [g] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'dadkh s yan %s', + past : 'yan %s', + s : 'imik', + m : 'minuḍ', + mm : '%d minuḍ', + h : 'saɛa', + hh : '%d tassaɛin', + d : 'ass', + dd : '%d ossan', + M : 'ayowr', + MM : '%d iyyirn', + y : 'asgas', + yy : '%d isgasn' + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : Morocco Central Atlas Tamaziɣt (tzm) + //! author : Abdel Said : https://github.com/abdelsaid + + var tzm = moment__default.defineLocale('tzm', { + months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), + monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), + weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS: 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'dddd D MMMM YYYY HH:mm' + }, + calendar : { + sameDay: '[ⴰⵙⴷⵅ ⴴ] LT', + nextDay: '[ⴰⵙⴽⴰ ⴴ] LT', + nextWeek: 'dddd [ⴴ] LT', + lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT', + lastWeek: 'dddd [ⴴ] LT', + sameElse: 'L' + }, + relativeTime : { + future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s', + past : 'ⵢⴰⵏ %s', + s : 'ⵉⵎⵉⴽ', + m : 'ⵎⵉⵏⵓⴺ', + mm : '%d ⵎⵉⵏⵓⴺ', + h : 'ⵙⴰⵄⴰ', + hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ', + d : 'ⴰⵙⵙ', + dd : '%d oⵙⵙⴰⵏ', + M : 'ⴰⵢoⵓⵔ', + MM : '%d ⵉⵢⵢⵉⵔⵏ', + y : 'ⴰⵙⴳⴰⵙ', + yy : '%d ⵉⵙⴳⴰⵙⵏ' + }, + week : { + dow : 6, // Saturday is the first day of the week. + doy : 12 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : ukrainian (uk) + //! author : zemlanin : https://github.com/zemlanin + //! Author : Menelion Elensúle : https://github.com/Oire + + function uk__plural(word, num) { + var forms = word.split('_'); + return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); + } + function uk__relativeTimeWithPlural(number, withoutSuffix, key) { + var format = { + 'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин', + 'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин', + 'dd': 'день_дні_днів', + 'MM': 'місяць_місяці_місяців', + 'yy': 'рік_роки_років' + }; + if (key === 'm') { + return withoutSuffix ? 'хвилина' : 'хвилину'; + } + else if (key === 'h') { + return withoutSuffix ? 'година' : 'годину'; + } + else { + return number + ' ' + uk__plural(format[key], +number); + } + } + function weekdaysCaseReplace(m, format) { + var weekdays = { + 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'), + 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'), + 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_') + }, + nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ? + 'accusative' : + ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ? + 'genitive' : + 'nominative'); + return weekdays[nounCase][m.day()]; + } + function processHoursFunction(str) { + return function () { + return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT'; + }; + } + + var uk = moment__default.defineLocale('uk', { + months : { + 'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'), + 'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_') + }, + monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'), + weekdays : weekdaysCaseReplace, + weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD.MM.YYYY', + LL : 'D MMMM YYYY р.', + LLL : 'D MMMM YYYY р., HH:mm', + LLLL : 'dddd, D MMMM YYYY р., HH:mm' + }, + calendar : { + sameDay: processHoursFunction('[Сьогодні '), + nextDay: processHoursFunction('[Завтра '), + lastDay: processHoursFunction('[Вчора '), + nextWeek: processHoursFunction('[У] dddd ['), + lastWeek: function () { + switch (this.day()) { + case 0: + case 3: + case 5: + case 6: + return processHoursFunction('[Минулої] dddd [').call(this); + case 1: + case 2: + case 4: + return processHoursFunction('[Минулого] dddd [').call(this); + } + }, + sameElse: 'L' + }, + relativeTime : { + future : 'за %s', + past : '%s тому', + s : 'декілька секунд', + m : uk__relativeTimeWithPlural, + mm : uk__relativeTimeWithPlural, + h : 'годину', + hh : uk__relativeTimeWithPlural, + d : 'день', + dd : uk__relativeTimeWithPlural, + M : 'місяць', + MM : uk__relativeTimeWithPlural, + y : 'рік', + yy : uk__relativeTimeWithPlural + }, + // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason + meridiemParse: /ночі|ранку|дня|вечора/, + isPM: function (input) { + return /^(дня|вечора)$/.test(input); + }, + meridiem : function (hour, minute, isLower) { + if (hour < 4) { + return 'ночі'; + } else if (hour < 12) { + return 'ранку'; + } else if (hour < 17) { + return 'дня'; + } else { + return 'вечора'; + } + }, + ordinalParse: /\d{1,2}-(й|го)/, + ordinal: function (number, period) { + switch (period) { + case 'M': + case 'd': + case 'DDD': + case 'w': + case 'W': + return number + '-й'; + case 'D': + return number + '-го'; + default: + return number; + } + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 1st is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : uzbek (uz) + //! author : Sardor Muminov : https://github.com/muminoff + + var uz = moment__default.defineLocale('uz', { + months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'), + monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), + weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'), + weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'), + weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'), + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM YYYY', + LLL : 'D MMMM YYYY HH:mm', + LLLL : 'D MMMM YYYY, dddd HH:mm' + }, + calendar : { + sameDay : '[Бугун соат] LT [да]', + nextDay : '[Эртага] LT [да]', + nextWeek : 'dddd [куни соат] LT [да]', + lastDay : '[Кеча соат] LT [да]', + lastWeek : '[Утган] dddd [куни соат] LT [да]', + sameElse : 'L' + }, + relativeTime : { + future : 'Якин %s ичида', + past : 'Бир неча %s олдин', + s : 'фурсат', + m : 'бир дакика', + mm : '%d дакика', + h : 'бир соат', + hh : '%d соат', + d : 'бир кун', + dd : '%d кун', + M : 'бир ой', + MM : '%d ой', + y : 'бир йил', + yy : '%d йил' + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 7 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : vietnamese (vi) + //! author : Bang Nguyen : https://github.com/bangnk + + var vi = moment__default.defineLocale('vi', { + months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'), + monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'), + weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'), + weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), + weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), + meridiemParse: /sa|ch/i, + isPM : function (input) { + return /^ch$/i.test(input); + }, + meridiem : function (hours, minutes, isLower) { + if (hours < 12) { + return isLower ? 'sa' : 'SA'; + } else { + return isLower ? 'ch' : 'CH'; + } + }, + longDateFormat : { + LT : 'HH:mm', + LTS : 'HH:mm:ss', + L : 'DD/MM/YYYY', + LL : 'D MMMM [năm] YYYY', + LLL : 'D MMMM [năm] YYYY HH:mm', + LLLL : 'dddd, D MMMM [năm] YYYY HH:mm', + l : 'DD/M/YYYY', + ll : 'D MMM YYYY', + lll : 'D MMM YYYY HH:mm', + llll : 'ddd, D MMM YYYY HH:mm' + }, + calendar : { + sameDay: '[Hôm nay lúc] LT', + nextDay: '[Ngày mai lúc] LT', + nextWeek: 'dddd [tuần tới lúc] LT', + lastDay: '[Hôm qua lúc] LT', + lastWeek: 'dddd [tuần rồi lúc] LT', + sameElse: 'L' + }, + relativeTime : { + future : '%s tới', + past : '%s trước', + s : 'vài giây', + m : 'một phút', + mm : '%d phút', + h : 'một giờ', + hh : '%d giờ', + d : 'một ngày', + dd : '%d ngày', + M : 'một tháng', + MM : '%d tháng', + y : 'một năm', + yy : '%d năm' + }, + ordinalParse: /\d{1,2}/, + ordinal : function (number) { + return number; + }, + week : { + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : chinese (zh-cn) + //! author : suupic : https://github.com/suupic + //! author : Zeno Zeng : https://github.com/zenozeng + + var zh_cn = moment__default.defineLocale('zh-cn', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), + longDateFormat : { + LT : 'Ah点mm分', + LTS : 'Ah点m分s秒', + L : 'YYYY-MM-DD', + LL : 'YYYY年MMMD日', + LLL : 'YYYY年MMMD日Ah点mm分', + LLLL : 'YYYY年MMMD日ddddAh点mm分', + l : 'YYYY-MM-DD', + ll : 'YYYY年MMMD日', + lll : 'YYYY年MMMD日Ah点mm分', + llll : 'YYYY年MMMD日ddddAh点mm分' + }, + meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, + meridiemHour: function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '凌晨' || meridiem === '早上' || + meridiem === '上午') { + return hour; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } else { + // '中午' + return hour >= 11 ? hour : hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 600) { + return '凌晨'; + } else if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar : { + sameDay : function () { + return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT'; + }, + nextDay : function () { + return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT'; + }, + lastDay : function () { + return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT'; + }, + nextWeek : function () { + var startOfWeek, prefix; + startOfWeek = moment__default().startOf('week'); + prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]'; + return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm'; + }, + lastWeek : function () { + var startOfWeek, prefix; + startOfWeek = moment__default().startOf('week'); + prefix = this.unix() < startOfWeek.unix() ? '[上]' : '[本]'; + return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm'; + }, + sameElse : 'LL' + }, + ordinalParse: /\d{1,2}(日|月|周)/, + ordinal : function (number, period) { + switch (period) { + case 'd': + case 'D': + case 'DDD': + return number + '日'; + case 'M': + return number + '月'; + case 'w': + case 'W': + return number + '周'; + default: + return number; + } + }, + relativeTime : { + future : '%s内', + past : '%s前', + s : '几秒', + m : '1 分钟', + mm : '%d 分钟', + h : '1 小时', + hh : '%d 小时', + d : '1 天', + dd : '%d 天', + M : '1 个月', + MM : '%d 个月', + y : '1 年', + yy : '%d 年' + }, + week : { + // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 + dow : 1, // Monday is the first day of the week. + doy : 4 // The week that contains Jan 4th is the first week of the year. + } + }); + + //! moment.js locale configuration + //! locale : traditional chinese (zh-tw) + //! author : Ben : https://github.com/ben-lin + + var zh_tw = moment__default.defineLocale('zh-tw', { + months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), + monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), + weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), + weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), + weekdaysMin : '日_一_二_三_四_五_六'.split('_'), + longDateFormat : { + LT : 'Ah點mm分', + LTS : 'Ah點m分s秒', + L : 'YYYY年MMMD日', + LL : 'YYYY年MMMD日', + LLL : 'YYYY年MMMD日Ah點mm分', + LLLL : 'YYYY年MMMD日ddddAh點mm分', + l : 'YYYY年MMMD日', + ll : 'YYYY年MMMD日', + lll : 'YYYY年MMMD日Ah點mm分', + llll : 'YYYY年MMMD日ddddAh點mm分' + }, + meridiemParse: /早上|上午|中午|下午|晚上/, + meridiemHour : function (hour, meridiem) { + if (hour === 12) { + hour = 0; + } + if (meridiem === '早上' || meridiem === '上午') { + return hour; + } else if (meridiem === '中午') { + return hour >= 11 ? hour : hour + 12; + } else if (meridiem === '下午' || meridiem === '晚上') { + return hour + 12; + } + }, + meridiem : function (hour, minute, isLower) { + var hm = hour * 100 + minute; + if (hm < 900) { + return '早上'; + } else if (hm < 1130) { + return '上午'; + } else if (hm < 1230) { + return '中午'; + } else if (hm < 1800) { + return '下午'; + } else { + return '晚上'; + } + }, + calendar : { + sameDay : '[今天]LT', + nextDay : '[明天]LT', + nextWeek : '[下]ddddLT', + lastDay : '[昨天]LT', + lastWeek : '[上]ddddLT', + sameElse : 'L' + }, + ordinalParse: /\d{1,2}(日|月|週)/, + ordinal : function (number, period) { + switch (period) { + case 'd' : + case 'D' : + case 'DDD' : + return number + '日'; + case 'M' : + return number + '月'; + case 'w' : + case 'W' : + return number + '週'; + default : + return number; + } + }, + relativeTime : { + future : '%s內', + past : '%s前', + s : '幾秒', + m : '一分鐘', + mm : '%d分鐘', + h : '一小時', + hh : '%d小時', + d : '一天', + dd : '%d天', + M : '一個月', + MM : '%d個月', + y : '一年', + yy : '%d年' + } + }); + + var moment_with_locales = moment__default; + moment_with_locales.locale('en'); + + return moment_with_locales; + +})); \ No newline at end of file diff --git a/public/photos/1/1/sada/56c160fbad635.jpg b/public/photos/1/1/sada/56c160fbad635.jpg deleted file mode 100644 index 160ea37c8..000000000 Binary files a/public/photos/1/1/sada/56c160fbad635.jpg and /dev/null differ diff --git a/public/photos/1/1/sada/thumbs/56c160fbad635.jpg b/public/photos/1/1/sada/thumbs/56c160fbad635.jpg deleted file mode 100644 index 992c993a9..000000000 Binary files a/public/photos/1/1/sada/thumbs/56c160fbad635.jpg and /dev/null differ diff --git a/release-notes.txt b/release-notes.txt new file mode 100644 index 000000000..69e497763 --- /dev/null +++ b/release-notes.txt @@ -0,0 +1,2671 @@ +activeCollab 3.3.0 [2013/03/26] +================================================================================ + +First beta release. Major new features: + + 1. Auto-upgrade + 2. Numerious invoicing improvements + 3. Projects on a timeline + 4. Workload report + 5. Improved main menu and navigation + 6. Invite People dialog + 7. Disk Utility + +activeCollab 3.2.12 [2013/03/18] +================================================================================ + +Enhancements: + + 1. More prominent warning that SVN communication via command line is + deprecated and will be removed in activeCollab 4 + 2. Simplified source settings dialogs + 3. Installation and upgrade scripts can detect Suhosin patch and extension + 4. Improved signature and quote cleaning when importing email + 5. Links added to visual editor can be forced to open in new browser window + 6. Added warning to New Incoming Mailbox for that clarifies what might + happen if users use personal addresses with activeCollab's incoming mail + feature + +Bug Fixes: + + 1. Fixed assignment filter print when filter is showing tracked time data + 2. Fixed issue when users and companies that already had an account but were + deleted, are imported from vCard + 3. Fixed issue where incoming mail would crash when invalid language + instance was provided + 4. Fixed activeCollab 2.3 project upgrade. Paused and canceled projects are + properly labeled now + 5. Page tabs at client invoicing section are properly localised now + 6. Mobile view of task page now shows related tasks + 7. Fixed issue that stopped users from loading more than 100 repositories in + Administration > Source Settings section + 8. System no longer allows users to send a quote to owner company + 9. Fixed issue when quote issued to owner company could not be deleted + 10. Fixed issue where some items could be duplicated in Outline view + 11. Fixed multi-byte issue when timeline background images are generated + 12. Improved the way system handles BCC-ed incoming mail + 13. "Set new password" button text can now be localised + 14. IAssigneesImplementation::getAllAssigneeIds() method now works properly + 15. Installer no longer uses persistent MySQL connections + 16. Fixed error where textarea was not displayed in some cases to users who + turned off visual editor + 17. Increased font size of group headers in printed reports + 18. boolval() function is defined if not present (PHP 5.5 introduces this + function while older versions of PHP don't have it) + 19. Fixed issue where private comment content could be lost upon recurring + profile update + 20. Fixed invoice PDF problem when project name had & in its name + 21. Invoice notes are listed alphabetically in WebKit powered browsers + +activeCollab 3.2.11 [2013/02/25] +================================================================================ + +Enhancements: + + 1. Compatibility update - this release can load upgrade information from + versions of activeCollab that use PHAR packages + +Bug Fixes: + + 1. Fixed compiled routes and templates routine + +activeCollab 3.2.10 [2013/02/21] +================================================================================ + +Enhancements: + + 1. Added option to select multiple time records and expenses and mass-change + their billable status + 2. Added quick view for completed objects displayed in Day Overview + home-screen widget + 3. Link to Item can be limited to search only in current project + 4. Added progress field to project's and milestone's detailed API response + that shows percent done, total number of tasks and number of open tasks + 5. Improved /info/roles API response + +Bug Fixes: + + 1. Fixed crash when incoming mail filter is being deleted in a new tab + 2. Fixed the way email notification are displayed on iPad + 3. Multiple localisation tweaks and fixes + 4. Fixed a bug where incoming mail could import an empty body when message + charset was not specified + 5. Fixed width of message field in Maintenance Mode dialog + 6. When project is created from a template, custom template settings are + applied to the new project as well + 7. Module icons are shown for disabled modules as well + 8. Fixed issue when one or more items gets added to objects list to + previously not visible group, and the group remained collapsed instead of + appearing expanded + 9. Fixed URL for attachments that are displayed at public pages + 10. Fixed issue with left list padding in content block + 11. Different number style for different levels of ordered lists + 12. Home screen will skip widgets and tabs that are not available if parent + module gets disabled + 13. Generic "This page is not available on mobile device" page is displayed + when visitor tries to open a page that does not have a mobile version + 14. Fixed issue with public tasks form on mobile devices + 15. Code that checks whether InnoDB support is available has been improved + (MySQL 5.6 compatibility tweak) + 16. When deleting quotes, automatically reset based on values for projects + 17. Made sure that long project names do not break Related Tasks dialog + 18. When task is copied, its most recent estimate is copied as well (this + functionality is used when projects are created from templates, too) + 19. Module clean-up on uninstallation improvements + 20. Fixed SVN over HTTPS error + 21. Projects are properly sorted in Add to Projects dialog + 22. Fixed issue when subtasks did not get rescheduled when their parent does + not have a due date set + 23. Fixed crash that could happen when user was removed from a project + 24. When time is tracked from a timesheet page, system uses proper default + visibility status (configured globally or per project) + 25. Long object type in recent activities widget no longer wraps + 26. Fixed project listing in mobile interface (it used to list only active + projects) + 27. SVN properly works when repository is actually a subfolder, nor root + folder of the repository + 28. Fixed milestone progress calculation for situations when big milestone + is close to completion, but not completed yet + 29. Fixed quick view navigation error + 30. Improved email cleaner for messages received from GMail + 31. Fixed a small vCard import error + 32. When temporal attachments are removed, object contexts are properly + cleaned up + +activeCollab 3.2.9 [2013/01/30] +================================================================================ + +Enhancements: + + 1. HTML root element uses language code based on user's language + 2. Link in email notifications for downloading PDF version of a quote + doesn't require login + 3. Improved performance of People page for users who have a lot of accounts + defined in their system + 4. When milestone is moved from one project to another, system will also + move archived tasks, discussions and files that belong to that milestone + 5. Email notifications for tasks now show task's due date (if set) + 6. Big email replies are imported as attachments + 7. Improved instructions for Scheduled Tasks setup on Windows + +Bug Fixes: + + 1. When user is removed from a project (or replaced), reminders that belong + to that user are cleaned up as well + 2. Fixed multiple translation issues + 3. Fixed styling on project budget page + 4. Outline properly displays task category when Edit form is opened + 5. Fixed issue that caused double activity log entries when file was + uploaded via API + 6. Fixed issue with commit path in Source module + 7. Fixed creation date display for recurring profiles + 8. Fixed issue with Recent Activities page in mobile interface + 9. Removed navigation block and Complete option from trashed objects in + mobile interface + 10. Fixed a minor problem with invoice issuing form + 11. Fixed issue with project template not being imported after a project + based on quote or project request is created + 12. Fixed issue where Notify People box in forms in Documents section also + listed archived users + 13. Fixed error during project creating step when quote items had to be + converted into project milestones + 14. Fixed minor issue with discussion details loading + 15. Fixed crash report when tracking report was executed, but there was no + tasks module installed + 16. Improved email notifications so they display properly in vast majority of + email clients + 17. Fixed time zone issue in Day Overview widget + +activeCollab 3.2.8 [2013/01/10] +================================================================================ + +Enhancements: + + 1. If user is visiting activeCollab with unsupported version of Internet + Explorer, or IE running in Compatibility mode, they will be warned + 2. Force HTML powered file uploads in Internet Explorer + 3. Project name added to project request notifications + +Bug Fixes: + + 1. Properly handle Esc when closing dialogs + 2. Fixed permissions issue when subtasks assignees could not complete + subtasks unless they were assigned to the parent task + 3. Fixed Internet Explorer issue where you had to click twice to open a + project tab + 4. Fixed links in notifications sent to users that don't have an account in + the system + 5. Fixed issue where Outline would stop working if Tracking module was + missing + 6. Covered one more SVN error condition + 7. Fixed issue where users were not redirected to new project after they + moved a project object + 8. Fixed invoice logo URL issue when system is using clean URL-s + 9. Fixed issue that forced default project visibility on new objects + +activeCollab 3.2.7 [2012/12/26] +================================================================================ + +Enhancements: + + 1. Tweaked subject of reassignment email notification + 2. Payment notifications are configurable now. On top of notifying all + financial managers, you can select to notify just specific manager or + turn off this notification + 3. Turn on or off email notification that are sent to clients when invoice + is fully paid + 4. Turn on or off email notification that are sent to clients when invoice + is canceled + 5. Added API commands for listing recent activities. This option is + available globally, per project and per user + 6. Information about task creation can be posted via API call + 7. Quick View added to Day Overview widget + 8. Quotes that are Sent, Won or Lost can be deleted + +Bug Fixes: + + 1. Remove Manage Project People link that was displayed to client company + managers (even though the could not use the tool) + 2. Fixed "Minuts" option in Who is Online home screen widget + 3. Various Internet Explorer fixes + +activeCollab 3.2.6 [2012/12/14] +================================================================================ + +Enhancements: + + 1. Added branching support to Source module + +Bug Fixes: + + 1. Fixed disk space calculation on 32-bit version of PHP + 2. Fixed start date display in recurring profiles + 3. Tweaked file, bookmark and YouTube video shared pages in mobile interface + 4. If project request text is not provided, request text box is not + displayed in mobile interface + +activeCollab 3.2.5 [2012/12/13] +================================================================================ + +Enhancements: + + 1. Separated modules that ship with activeCollab and custom modules on + Administration > Modules page + 2. Added option to disable all custom modules with a single click + +Bug Fixes: + + 1. Hiding project budget in Small Biz (does not have budgeting features) + 2. When object is created via API, use default project visibility instead of + private visibility + 3. Fixed issue when project is created from template and there was a source + repository associated with template project + 4. Trashed and deleted milestones are no longer displayed on calendars + 5. Quote details page can be viewed using mobile device + 6. Fixed issue where documents module would print full documents list + instead of a single document + 7. Fixed problem where edit project form would not load custom field values + 8. Fixed public page link issue on quite details page + 9. Fixed user display issue in source module (printed HTML instead of links) + 10. Fixed minor filtering issue in Invoices section + 11. Fixed check that determine whether image can be previewed or not (some + images were missed by existing method) + 12. Fixed bug when attachments could not be attached to comments using the + main interface + 13. Fixed issue when Microsoft Excel treated assignment filter export as + symbolic links because they started with ID string + 14. Fixed problem where project did not pick up custom field values when it + was created + 15. Fixed error when invoice due date settings (configured in Administration + panel) were always forced + 16. Fixed potential crash in tracking reports where conditions are so strict + that there is no project that meets them + 17. Improved email details dialog layout in Admin > Email section + +activeCollab 3.2.4 [2012/11/26] +================================================================================ + +Bug Fixes: + + 1. Fixed code snippets error + 2. Shared notebooks can be accessed via mobile device + 3. Added icon for PPTX documents + 4. Fixed issue when expense category was not properly saved when tracking + report was saved + 5. Fixed issue where Tasks module could not be installed unless it is + installed during system installation or upgrade + +activeCollab 3.2.3 [2012/11/20] +================================================================================ + +Bug Fixes: + + 1. Fixed issue with upgrade script + 2. Fixed numerous PHP notices (due to static calls to methods that are not + declared as static in generated model classes) + 3. Fixed issue with thumbnail and CAPTCHA generation + 4. Improved text cleanup on email import + +activeCollab 3.2.2 [2012/11/16] +================================================================================ + +Enhancements: + + 1. Assignment filters now also take into account task's position when they + are displaying data (works when tasks are not or grouped, or when they + are grouped by due date) + 2. Improved contrast of drag handle icon and changed cursor to move when + hovering over drag handle on Incoming Mail Filters page + 3. Added mobile views for public pages of objects that are shared + +Bug Fixes: + + 1. Fixed issue with upgrade script and default tax rate + +activeCollab 3.2.1 [2012/11/14] +================================================================================ + +Enhancements: + + 1. Tweaked wording for creation entries in activity logs + 2. Browse archive link instead of a button in sections where there are + archives (projects, tasks etc) + 3. Easily unsubscribe from future notifications about particular object + directly from within email notification that user received + 4. Added option to configure default tax rate + 5. System will warn users if they try to navigate away from the page where + they have inserted a comment, but haven't submitted it + 6. Added keyboard shortcuts to Quick Jump and Quick Add tools (Ctrl+Shift+J + for Quick Jump and Ctrl+Shift+Q for Quick Add) + 7. Quick Jump and Quick Add can be navigated with keyboard + 8. Time & Expenses Report: Added billable filter that returns billable, + pending payment and paid records + 9. Archive related tasks are displayed as well, not just active ones + 10. Project requests are displayed as tab on client company page + +Bug Fixes: + + 1. Fixed issue where creation of category from select box would break + categories that were already in the select box + 2. Fixed issue where permanently deleted global documents were still visible + in recent activities + 3. Clean up routing cache when module is uninstalled, to cover cases where + module was overriding routes used by activeCollab + 4. Fixed Quick Add Project button + 5. Date picker on New Time Record form for task now uses date in user's + time zone, instead of GMT date + 6. Fixed issue where system allowed Add People form to be submitted even + when there is no users selected + 7. Fixed issue where brief project info could not be loaded if project was + created based on a quote or project request + 8. Notify users list in Global Document section checks for access + permissions when listing users + 9. Add Client to People option removed form public quote page + 10. System properly updates file list on milestone page when multiple files + are uploaded + 11. Fixed issue when installed activeCollab version was ahead of latest + stable version (like beta releases) + +activeCollab 3.2.0 [2012/11/06] +================================================================================ + +First activeCollab 3.2 beta build. Major new features and improvements: + + 1. Quick View enables easy preview and management of application objects + 2. Quick View for Attachments + 3. Related Tasks provides quick and easy way to connect related tasks + 4. Custom Fields for Tasks and Projects + 5. HTML5 based upload (instead of Flash powered implementation) + +activeCollab 3.1.18 [2012/11/02] +================================================================================ + +Enhancements: + + 1. After successful password reset, user is automatically logged in and + taken to the home screen + 2. System generates longer, more secure random passwords (20 letters, mixed + letter case, including numbers and symbols included) + 3. On successful login automatically rehash password using PBKDF2 if we have + SHA1 hashed value in the database + 4. New User form tweaked to look like other forms in the system and better + explain behaviour of options that are turned off by default + +Bug Fixes: + + 1. When user tries to create a new mailbox with reserved email address, + Email Reply to Comment tool will report a proper message + 2. Fixed issue where anonymous users would receive notifications about + comments that they post + 3. Fixed reset password issue in IE8 and IE9 + 4. Fixed issue where system would ignore users' time zone when sending + scheduled reminders + 5. Mobile Interface: Fixed issue where post comment form was visible even + when comments were locked + 6. Mobile Interface: fixed notebooks page on milestone level + 7. Mobile Interface: fixed files page on milestone level + 8. Fixed issue with latest version number checking + 9. Upgrade Script: fixed issue where text_document_versions and + file_versions tables were created even when files module was not + installed + 10. Fixed issue with estimates report (it used to query permanently deleted + and trashed time records) + 11. Fixed issue where project progress was displayed even to people who don't + have access to tasks and to do lists on the project + +activeCollab 3.1.17 [2012/08/26] +================================================================================ + +Enhancements: + + 1. System uses PBKDF2 to hash passwords instead of SHA1 + 2. Notification sent to new assignee includes full tasks/milestone + description and attachments + 3. Added option to reorder milestones that start on the same date + 4. Improved quote and signature stripping for replies sent using Windows + Live Mail and iPad Mail + 5. Control Tower now shows if there's a new version of activeCollab + available for download + 6. Links in imported email messages are automatically made clickable + 7. Different icons for different log types in email log + 8. Assignment filter are aware of subtask due dates when they are grouping + data by due date + 9. Assignment filter will automatically set additional fields when user + decides to include time data + 10. When draft invoice has number set, system will treat it as pro-forma + invoice + option to specify how pro-forma invoices are called + 11. Added tile icons used by Windows 8 + 12. Added /info/job-types API command + +Bug Fixes: + + 1. /info properly returns read only flag + 2. Use "Sale" instead of "Authorisation" when processing card with PayPal + 3. Fixed bug where Insert Link tool in visual editor would strip white space + around selected text + 4. Fixed issue where activeCollab would ignore recipients's language + settings and sent email notifications in default language + 5. Fixed copy phrase problem for long phrases in translation tool + 6. Fixed collision between "Reopen on New Comments" option and completion of + parent objects using a comment form + 7. Fixed long body line display issue in IE9 + 8. Fixed issue when Insert Image tool would always add image at the + beginning of text block in IE9 + 9. License and new version check properly checks for branding removal + 10. Job types API response includes is_default flag + 11. Fixed GIT update silent failing when URL path is changed + 12. Fixed big logo issue in invoice PDF + 13. Fixed GIT update issue when GIT repository is empty + +activeCollab 3.1.16 [2012/08/17] +================================================================================ + +Enhancements: + + 1. Improved and documented API commands and responses + 2. When translating long phrases, system offers text area instead of single + line text input + 3. Added priority and label to non-completed objects in Day Overview + 4. Incoming mailbox auto-disable feature is now configurable + 5. Added option not to print footer in invoice and quote PDF-s + +Bug Fixes: + + 1. Fixed issue where archived projects would not display any data on + Time & Expenses page + 2. Colors for YouTube Videos and Bookmarks in Recent Activities + 3. Fixed display of client address in quote PDF + 4. Fixed date display on Milestones printout + 5. Fixed showing raw HTML in quote's description when it is created from a + project request + 6. Fixed aggregate tasks report crash on long milestone names + 7. Improved height and width calculation when company logo is being added to + invoice PDF-s + 8. Fixed outline issue when milestone, task or subtask had " in the name + 9. Fixed conflicts count label + 10. Fixed Load More link issue in advanced search + 11. HTML::toPlainText() no longer prepends each paragraph with a tab (\t) + 12. Anonymous subscribers' permissions are not evaluated any more upon + copying or moving an object to another project + 13. Log Time and Log Expense dialogs are aware of user's time zone when + pre-selecting date + 14. Fixed bug that sometimes appeared upon populating client data when a + quote is created from a project request + 15. Fixed issue with checking public quote's status + 16. Moving an object now moves anonymous subscriptions as well + 17. Fixed issue with printing in Internet Explorer + 18. Fixed issue when GIT repositories are checked via scheduled tasks + +activeCollab 3.1.15 [2012/08/11] +================================================================================ + +Enhancements: + + 1. Added option to resend sent and won quotes + 2. Added project archive on company and user profile pages + +Bug Fixes: + + 1. Fixed CSS error that could result in some stylesheets not being applied + 2. Fixed error when default hourly rate for a job type was updated + +activeCollab 3.1.14 [2012/08/09] +================================================================================ + +Enhancements: + + 1. Control Tower helps administrators spot problems early on + 2. Email notifications when milestones, tasks and subtasks are reassigned + 3. Source module will recognise .info, .install and .module files as text + files (based on Drupal naming convention) + 4. Existing language can be updated with translation file + 5. Images will open inline in a new browser tab or window, instead of always + being downloaded to disk + 6. Project overview printout improved + 7. Project specific task ID is now in a separate column in CSV export + 8. Assignment filters can load estimated and tracked time + 9. Added option to turn off result number limit when time & expenses log is + requested via API + 10. Estimated vs Tracked time report added + 11. Day Overview now displays object priority + 12. Less CSS and JavaScript files (less files to upload means faster upgrade) + +Bug Fixes: + + 1. License key is sent to JavaScript only in administration section + 2. Logs are not kept when system is in production mode + 3. Fixed counting unread messages in IMAP/POP3 mailbox + 4. Favourites listing will not show permanently deleted items + 5. Fixed problem that prevented custom date option for Issue Invoice dialog + 6. Fixed a bug where text documents, files, you tube vides and bookmarks + could not be copied to another project + 7. Fixed issue with incorrectly displayed user in Day Overview widget + 8. Fixed issue with incorrect sum of total time logged by selected user in + Day Overview widget + 9. Fixed bug when number of users on a project was not displayed correctly + at 'project brief' page + 10. NaN.NaN in tracked time and expenses widgets fixed + 11. Fixed issue with being able to archive your own company, or a company + where the last administrator is in + 12. Fixed bug when filenames in Files module have been appended with counters + even if the old files were permanently deleted + +activeCollab 3.1.13 [2012/09/26] +================================================================================ + +Enhancements: + + 1. Task time and expenses widget now shows task estimate as well + 2. Reply to Comment checklist makes configuration and troubleshooting of + that feature much easier + 3. Default due date can be pre-configured on recurring profile level + 4. Default billable flag value can be set globally and per project + 5. Improved select project permissions widget + 6. Simplified and improved Add People dialog + 7. Users can be replaced with a user that's already on a project + 8. Current day is highlighted on project timeline + 9. Notifications for incoming mail conflicts have beed added + 10. Better options for removing incoming mail conflicts + 11. Project exporter now also exports text documents, bookmarks and YouTube + videos from project's Files section + 12. System will not allow for milestone to start on a day off or weekend + 13. Versions of text documents can be compered now + 14. Text document can be revered to one of the older versions + 15. Simplified project listings in company and user pages + 16. Sending an email notification to client is now optional if project + request is created from Projects > Project Requests section + 17. Upon creating a new project request, user that is selected to be in + charge for that request is automatically subscribed to it + 18. Links in subtasks are automatically made clickable + 19. TCPDF now supports characters from Chinese, Japanese etc languages + 20. Included link to user assignments project page when user is replacing + someone on a project + 21. Reminders widget added to the default set of widgets that are created + when activeCollab is installed + 22. Information on whether recipient is responsible or assigned is included + in task and milestone notifications + +Bug Fixes: + + 1. Fixed bug where public submit form offered only projects that + administrator is directly involved with, instead of listing all available + projects + 2. My Discussions widget looks through all projects for administrators and + project managers, instead of including only projects that they are + directly involved with + 3. Fixed NaN total in time reports + 4. Fixed double HTML cleaning in status messages + 5. Fixed issue when Resend Invoice would say that email was sent even in + situations where there was no email notification + 6. Fixed a problem that could stop new objects from being saved when + Documents, Source or Tracking modules were uninstalled + 7. Fixed issue where project threw and error when tasks are being exported + and tracking module was not installed + 8. Fixed some SVN over executable bugs on Windows + 9. Long quote name is broken into multiple lines of text + 10. Get visible user ID-s and get visible company ID-s checks included + permanently deleted projects by mistake + 11. Fixed issue where source repositories could not be deleted from + Administration panel + 12. Formatting in public task forms is preserved + 13. When user is removed as responsible party from an assignment, all other + assignees are dropped and unsubscribed as well + 14. Fixed issue with object context rebuild for project objects + 15. Fixed issue when deleted time records and expenses were included in a new + invoice when invoice is based on a milestone + 16. Fixed bug when client for the quote created within activeCollab was not + subscribed automatically + 17. Project name is included as prefix of subject line for discussion related + notifications + 18. Line item quantity in recurring profiles does not need to be a whole + number any longer + 19. Milestone information is now hidden at view/add/edit pages when + Milestones tab is not used within a project + 20. Fixed issue when late and/or due milestones were visible at project's + index page without checking for appropriate permissions + 21. Removed /e modifier and made activeCollab works well when Suhohsin is + configured to disable eval in preg_match + 22. Extra radio button in Make a Payment dialog removed + 23. Fixed issue with "Reply Above This Line" stripping when reply was sent + from Yahoo! Mail + 24. Fixed "Reply Above This Line" stripping when that phrase is translated + and notification is not in English + 25. Fixed search result listing problem + 26. Fixed initial group checkbox values in select assignees helper + 27. Fixed bug in wrong pre-selected user at the 'edit quote' form + 28. Moving an object from one project to another now checks for + assignee/subscriber's permissions + +activeCollab 3.1.12 [2012/09/06] +================================================================================ + +Enhancements: + + 1. activeCollab can check for new version + 2. System can list both open and completed projects, as well as open or + completed only + 3. "Add as Comment" resolution option for incoming mail conflicts added + 4. Improved transliteration support + 5. Group by file name in Documents and Files sections are smarter when + working with non-latin names + 6. Project exporter now exports files + 7. Added note to a freshly submitted project request to let user know they + can bookmark the public page + 8. Added from/to labels to milestone filters + 9. Added company note field, with an appropriate permission in system role + 10. Invoices can be issued with due upon receipt, NET 10, NET 15, NET 30 and + NET 60 due date options + 11. Discussions are visually marked as read as soon as they are loaded + 12. Tasks use global {TASK/ID} identifier in email notifications + 13. Modules have default uninstall message, which includes the name of the + module + 14. Confirmations for uninstalling a module are using module's defined + message (or falling back to default if it's not defined) + 15. System shows "Loading" bar instead of black screen while loading backend + scripts and stylesheets + 16. "Help us Improve activeCollab" is configurable (Admin > General Settings) + +Bug Fixes: + + 1. Fixed php config to int conversion function + 2. Fixed template so proper person is listed as version author in New + Notebook Page Version email notification + 3. Fixed missing $context in 'forgot_password' email notification + 4. Fixed sorting in jump to tool, object lists and assignment filters + 5. Fixed issue with month not being displayed correctly in date range picker + 6. Financial managers see "Go to Invoice" instead of "Pay Online Now" link + in email notifications for issued invoices + 7. Fixed issues with week boundaries calculation in assignment and tracking + reports + 8. Exporter module will not try to create /work/export folder if that folder + already exists + 9. Fixed project assets URL (uses slug instead of project ID) + 10. Fixed issue with Files project tab initialisation + 11. Fixed saving 'based on' information for projects created from requests or + quotes + 12. New invoice created from a quote which has a project, now pre-selects + that project + 13. Setting system default options for invoice that's based on a report or a + quote + 14. Fixed invoice comment height so it does not overlap company info block + 15. Schedule task update checks if the connection to repository is valid + 16. Don't show Next Trigger On for archived recurring profiles + 17. Private invoice comment is saved when invoice is created from a tracking + report + 18. Upgrade script moves uncategorized pages to "Uncategorized Pages" + notebook instead of skipping them + 19. Delegated tasks widget now properly shows tasks delegated by selected + user + 20. Removed "not assigned tasks" options from Delegated tasks widget + (unassigned tasks aren't delegated - filter result is always empty) + 21. Fixed cleaning up HTML in text documents that caused all line breaks to + be lost after editing + 22. Fixed code styles in pages exported with Project Exporter tool + 23. Fixed issue when reassigning a task via comment to 'nobody' + 24. Fix for redirect loop in some environments which report working on port + 80 while they actually work at 443 ($_SERVER['HTTP_X_REAL_PORT']) + 25. Fix for frequently task being crashed when log about incoming mail has + invalid "from" email + 26. Reminders are cleared when parent object is deleted + 27. Fixed default billable status filter in time and expense widgets + 28. "Notify sender about task being created" option is forced for CC-ed + recipients as well + +activeCollab 3.1.11 [2012/08/21] +================================================================================ + +Enhancements: + + 1. Added "To Email" criterion to incoming mail filters + 2. Added support to login to the application using a third-party login form + 3. System will send messages that are set to be sent instantly but something + went wrong and they were not sent + 4. Logo URL in email notifications now includes timestamp to avoid caching + problems with some email clients + 5. Improved the way quotes handle existing and non-existing clients + 6. Project exports are grouped per project in /work/export folder + 7. Documents can be printed (in Documents section) + 8. Added .htaccess to /git and /hg folders with "Deny for all" + 9. Added repository type icons + 10. Completed tasks at project time log are now crossed-over + 11. Added user, day and billable status filters to time and expense widgets + 12. Added support to mark saved assignment filters as private (can be used + only by users who created them) + 13. Added option to unsubscribe unregistered users when sharing is turned off + for particular object + 14. Archived objects are now included into project's progress + 15. Budget report on project level now shows hourly rate, as well as number + of billable hours + 16. Owner company is listed above other companies in Add People dialog + 17. activeCollab now checks memory limit on installation + 18. Reminder comment is now listed in "Manage Reminders" dialog + +Bug Fixes: + + 1. Fixed bug when clearing the entire cache + 2. Fixed bug which prevented custom frontend layout to be used + 3. Fixed issue with assignment labels cache + 4. Changed getenv($env) to $_SERVER[$env] (getenv does not work in some IIS + servers) + 5. Fixed problem where mail log info was escaped twice + 6. Fixed application URL in email notifications + 7. Fixed issue in upgrade script's JS which was incorrectly guessing the URL + and failing to execute upgrade steps on rare occasions + 8. Fixed incorrect casting of 'no' value in yes_no_default helper + 9. Fixed a bug that could prevent the system from uploading an attachment + 10. Fixed a problem where status updates are cloned when one of the buttons + are clicked + 11. Visual editor macros fixed to work in Google Chrome + 12. Fixed mass mailer message template + 13. Logout simply shows login form if user is already logged out (from a + different window or by session expiry) + 14. Case insensitive checks if user is already subscribed (by email) + 15. Category is no longer a dead link in email notifications + 16. Images in description fields are properly resized to fit max email + notification width + 17. Code snippets in email notifications are properly formatted + 18. Some elements that could not be translated in 3.1.10 are covered now + 19. Checking for active session, reset password and forgot password actions + are now checking for user's status + 20. Quoting strings during CSV export now properly takes care about custom + CSV field separator + 21. Added styling for date range picker + 22. Fixed showing error dump instead of error message upon validation failure + at 'add user' dialog + 23. Project name is updated at project tabs without need for refreshing the + page + 24. New task is loaded after a task is copied to another project + 25. When task is rescheduled, subtasks are properly rescheduled as well + 26. Expense records are properly marked as paid, when invoice is paid + 27. When notebook is copied, system also copies archived notebook pages + 28. Invoice due on update is properly saved and displayed + 29. Fixed bug in quotes with setting recipient for quote edit + 30. Fixed incorrect linking to permanently deleted users/companies in Quotes + & Project requests + 31. Fixed an issue when source repository is deleted from admin page + 32. Fixed returning permanently deleted company by default, in case that + company is being looked up by name + 33. Fixed issues in Documents module for users that have permission to manage + documents + 34. Fixed potential issue with viewing Document objects by users who don't + have proper permissions + 35. Milestone is properly updated when object is moved from selected + milestone to a different milestone + 36. Project exporter will not create dead links on milestone details page + for objects that are not being exported + 37. Fixed error that caused Project Exporter to skip time and expense records + from export + 38. Fixed issue that stopped "users map" from opening to non-admin users + 39. Reloading job types after default one is changed so permissions of the + existing ones get properly updated + 40. Fixed issue with caching user's display name in project people list + 41. Fixed issue with loading permanently deleted company + 42. Fixed fatal error at public object's page when submitting a comment which + has validation errors + 43. Fixed error when trying to release time & expenses from an invoice when + its status is issued or paid + 44. Fixed access permission checks for Reports section + 45. Mitigated potential performance issue when copying many objects or + creating projects from a template + 46. Assignment filter's results exported to CSV now show labels properly + 47. Error message for min. password length now makes more sense + 48. Fixed a bug when the interface was not refreshing after uploading new + file version + 49. To Do lists now support subscribers + 50. Fixed notifications for assignees and subscribers of subtasks added to + tasks + 51. Notifications for subtask assignee in To Do list now work + 52. Fixed inconsistency at discussions add/edit form (one/two sidebars view) + 53. If user does not have permissions to track time, they will not be able to + set or update task estimate + 54. Fixed vCard import crash ($str needs to be scalar value) + 55. Due to various Opera bugs, version of page optimise for print opens a new + window instead of being printed in the background + 56. Upgrade script properly handles uncategorized pages + 57. Added server-side check for deleting the last home screen tab + 58. Fixed bug with upgrade script reporting too low memory limit in case that + it's set to -1 (unlimited) + 59. Fixed condition that finds recurring profiles that should be sent today + +activeCollab 3.1.10 [2012/07/12] +================================================================================ + +Enhancements: + + 1. Added ability to specify how invoices are called (so you can easily cover + situations where your country requires that invoices are displayed as + "Tax Invoice" for example) + 2. Files tab added to milestone details page + 3. Added options to sum time records and expenses when invoice is created + based on a result of a tracking report + +Bug Fixes: + + 1. Better clean up of home screen widgets and tabs on module uninstallation + 2. Sample Theme is automatically uninstalled by the upgrade script + 3. Fixed API error when file has versions + 4. Invoice related email notifications show note, not comment + 5. Task assignee is subscribed and notified + 6. Fixed issue with assignment filters and filtering by selected milestone + and / or category + 7. Milestone is preserved when project is created from a template + 8. Subtasks are properly rescheduled when milestone is rescheduled + 9. Fixed problem where New Subtask notification displayed person that + created parent task or to do list as subtask author + 10. Internet Explorer 8 slow script error covered + 11. Trash popup properly updates when one of the notebook pages that has + sub-pages is restored + 12. Interface does not break if user tries to log in after log out without + refreshing the page + 13. Fixed an error that shifted milestones one day back on timeline tab and + milestone details page + 14. Sample theme is automatically removed by the upgrade script + 15. User is redirected to Repositories page when source repository is removed + from a project + 16. Estimate can be updated in project outline + 17. Failed to load class 'EstimateInspectorProperty' error fixed on task + print page + +activeCollab 3.1.9 [2012/07/09] +================================================================================ + +Enhancements: + + 1. Email notifications: simplified templates + 2. Email notifications: improved readability on small screens + 3. Forms now wait for attachments to upload + 4. One click change label for subtasks + 5. Labels are displayed in object list for projects and tasks + 6. If object is private, little icon is displayed in the object list + 7. Comments widget now displays comment number + 8. System no longer sends four notifications when invoice is marked as paid + (it sends two now: one to payee, and one to financial managers) + 9. Added dd/mm/yy and dd/mm/yyyy date formats + 10. From, To, and Created on cells in e-mail log will no longer break into + more lines + 11. Inline images now support links + 12. Minor tweaks with sharing and non-registered users + 13. Tasks show task ID in title + 14. Page title is now in "Page Title - Site Name" format + 15. Design of redesigned reminder tightened up + 16. Project name included in comment, subtask and reminder notifications + 17. System will notify administrators when mailbox is auto-disabled + 18. activeCollab loads 30 instead of 50 recent activity entries + 19. Financial manager see all people (but can't manage their accounts) + 20. It's clear that project is archived when viewing Project at a Glance page + 21. Mobile Interface: Show only active tasks on My Assignments page + 22. Added Files tab to project milestone page + 23. Show/hide Add User button when company is trashed + 24. Parent information included in printed detailed tracking report + 25. Improved grouping of summarised tracking reports + 26. Tasks displayed at home screen widgets grouped by completion or creation + date are now sorted from newest to oldest date, respectively + 27. Saving client from quote will now update all existing quotes with same + (non-existing) client + 28. PDF that's attached to invoice related notifications always uses + "invoice.pdf" filename + 29. Duplicate quote + +Bug Fixes: + + 1. Email notifications: fixed escaped characters in email subjects + 2. Trash is properly update when last object in a group is removed + 3. Chrome specific: fixed issue were Jump To and Quick Add would not open + after Status Updates has been opened + 4. Fixed issue that occurred when Notebook is being moved to trash + 5. Updated CURL command to include -L switch (follow redirections) + 6. Updated checking isSubscribed method in case that subscriber is anonymous + user + 7. Fixed issue upon using select_assignees helper to manage subscriptions as + well (not all subscribers were properly pre-selected during Edit action) + 8. Assignee set via comment now gets subscribed to object as well + 9. Fixed deleted label appearing within the system after it's been deleted + (caching issue) + 10. Notification context code is included in the subject ONLY if context + object is commendable (user and invoices are not) + 11. Internal: MySQL connection throws an exception on invalid escape value + 12. Fixed bug on "Nudge" page in mobile interface + 13. Fix for incoming mail when filename of body part is forwarded as a + disposition parameter, and not as inline parameter + 14. Fixed issue where label name could break in two lines + 15. Fixed URL validator (it marked URL as invalid in case when they have & + character) + 16. Email subject is no longer HTML escaped + 17. Internal: Email validator now uses PHP's filter extension + 18. Internal: Shut-up for get_magic_quotes_gpc() (to remove deprecated + warnings from error logs) + 19. Internal: Ability to specify attachment's name has been added to + application mailer + 21. If "Notify sender" is not checked, don't notify sender + 22. Fixed wrong info for object author, creation date and completed status + upon copying the object to another project + 23. Fixed "forbidden" error for project manager / admin while trying to + subscribe to objects in projects that they aren't members of + 24. Fixed potential problem with day off update + 25. Fixed copy feature for archived objects + 26. Trashed objects now cannot be copied/moved + 27. Copying an object now removes relation to milestone + 28. Fixed issue that disabled Safe feature for tracking reports + 29. To do list category is properly updated when To Do list is edited + 30. Fixed error when non-submitted Project::add() API request ended up + loading template (instead of serving Bad Request error) + 31. Improved vCard importer and fixed some import related bugs + 32. Internet Explorer compatibility fixes + 33. Skip trying to subscribe public task creator if the same user is set to + be automatically subscribed in public task's settings + 34. Fixed links to different invoicing sections depending on user's company + (owner or not) + 35. Fixed issues where last payment was not marking Invoice as paid + 36. Better propagation of state changes when project is archived or trashed + (and restored from archive or trash) + 37. Upgrade script fixes issues with empty object texts + 38. Fixed visual bug after editing a quote (client-side fail) + 39. File is properly loaded when users visits it from email notification, but + needs to authenticate first + 40. Fixed bug when project manager or admin had to be added to projects in + order to see other user's tasks via home screen widgets + 41. Fixed bug when tasks grouped by completion date were showing only open + tasks + 42. Fixed inability to choose default language in user's profile after some + other language has been set as default + 43. Fixed saving theme config option for user (disabled until new support for + themes is introduced) + 44. Fixed issue where calendar duplicated events in last couple of days of + previous month, and appropriate days of current month + 45. Fixed validation issue during creation of a new quote + 46. Fixed issue that resulted in "Failed to Load" error when user tried to + open Recent Activities tab on user's profile + 47. Prevent user from submitting form for adding user to projects if there + are no more projects that user can be added to + 48. Fixed data integrity issue that could result in project object being + imported from multiple project instead of just from the template + 49. When user is replaced, assignments are properly moved to the new user + 50. Fixed issue where users who are automatically added to new projects all + start with no permissions + 51. Fixed "Send Welcome Message" dialog style + 52. Fixed "Notify Users About this Change" feature when user is being + replaced on a project + 53. In recurring profiles, company managers from owner company are excluded + from notifications if they don't have financial management permissions + 54. RSS feed is no longer empty + 55. Cache is cleared when project tabs are re-arranged on Administration > + Project Settings page + +activeCollab 3.1.8 [2012/06/18] +================================================================================ + +Enhancements: + + 1. History API patch is applied only to Internet Explorer + 2. Assignment delegation settings are available on project level + 3. More informative user login error messages + 4. Maintenance module re-introduced + 5. Invoice counter can have fixed string length (prefixed with zeros) + 6. Module management actions now refresh the entire page + 7. Default button color changed to green + 8. Improved design of flyout dialogs + +Bug Fixes: + + 1. Slow script bug fix for browsers that implement History API natively + 2. Fixed issue where Save As and Delete options for filters were displayed + even to users who can't use these actions + 3. Compiled templates are cleared when module is installed or uninstalled. + They are also cleared after each upgrade + 4. Fixed error when user tries to save a new notebook page version + +activeCollab 3.1.7 [2012/06/16] +================================================================================ + +Enhancements: + + 1. Force check that notifications are sent only to active users + +Bug Fixes: + + 1. When invoice notification is sent to a client, PDF version of the invoice + is included as an attachment + 2. Fixed Day Overview widget issue that resulted with query error + 3. Improved handling of notebook pages when notebooks and pages are moved to + trash and restored from trash + +activeCollab 3.1.6 [2012/06/15] +================================================================================ + +Enhancements: + + 1. New client side events: content_loaded and single_content_loaded + 2. Incoming mail will notify administrators if it fails to check mailbox + because of a validation error + 3. Client see person who issued an invoice, not a person who created it + 4. Activity logs are much faster now, and consume less resources + 5. Browser history manipulation improved on the AJAX load for the Projects + index page + 6. Day off name no longer needs to be unique + 7. Added archive for documents + 8. Invoice form: Add From Template option will overwrite default invoice item + if it is empty + 9. Quick search now can search for documents as well + 10. SVN can trust server certificate (added --trust-server-certificate to svn + executable call) + 11. My Discussions widget optionally displays discussions from completed + projects (off by default) + 12. Tracking reports display parent info for time records and expenses that + are tracked for a task + 13. Estimates use hour notation + 14. Defined default home screen for people managers (same as for project + managers for now) + 15. Quotes: saving client now optionally sends a welcome e-mail + + +Bug Fixes: + + 1. Rebuild localisation bug fixed + 2. Collectors show file path only when app is in debug or development mode + 3. Permanently deleted objects can't be accessed + 4. App.isValidEmail() is no longer case sensitive + 5. Situation when server_name is not properly set will no longer break the + system + 6. Break lines are no longer cleaned from paragraphs by HTML sanitizer + 7. activeCollab will obey Return-Path and Auto-Submitted email headers + 8. If someone adds an address of defined incoming mailbox to CC, that + address will not be automatically subscribed + 9. Quick search is more reliable + 10. Fixed message analyzer in source module + 11. Source module search index related bug has been covered + 12. Fixed repository upgrade issue + 13. Trashed users are not displayed on project people pages + 14. Show only visible repository project objects in source admin section + 15. Project progress refreshes when we change objects milestone or when we + move it to the trash + 16. Fixed print in invoices section that clients use + 17. Quick search: fixed bug where quick search would return objects that are + already deleted + 18. Quick search: fixed bug where users can't be found after their accounts + have been update + 19. Advanced search: fixed bug where advanced search would return objects + that are already deleted + 20. Tracking reports will display records for all selected users, not just + for the first one + 21. Trashed projects are no longer listed in tracking reports + 22. Upload files from shared task pages works now + 23. Error that happens when reminder is dismissed has been covered + 24. Fixed an error that happens when milestone is restored from trash + 25. Subtasks are properly showing in Day Overview widget + 26. Issue that caused recent activities blocks to be empty for clients has + been covered + 27. Delegated Tasks widget now properly displayed Delegation Settings on edit + 28. Add and edit company dialogs have the same width + 29. Fixed calculation issue that could leave an invoice open even after last + payment has been made + 30. Covered a rare issue that caused some of the objects not to be copied + from a template to the new project + + +activeCollab 3.1.5 [2012/06/08] +================================================================================ + +Enhancements: + + 1. My discussions widget now displays only active, non-archived projects. + Completed, non-archived projects can be optionally included + 2. File preview is download link for images and types that don't have inline + preview option + 3. FORCE_ROOT_URL is On by default + 4. Record parent displayed in Time & Expenses log + 5. Added option to Project Settings that lets administrator configure + whether clients can delegate tasks to all project members or just to + members of their own company that are on a project + 6. Completed objects are crossed over on project assignments page and in + assignment filter results + 7. After creating a new project from quote, user is redirected to that + project + 8. Outline: Faux milestone in outline view is now called 'Unclassified + Tasks and Todo Lists' not 'Unknown Milestone' + 9. Outline: New milestones are added before faux one, but after all existing + 10. Max upload size displayed in New File Version form + 11. Upgrade from 2.x should drop records from subscriptions that refer to + non-existing entries in users table + 12. System automatically scrolls down to the bottom of invoice items list + when there are many items in the list + +Bug Fixes: + + 1. Fixed missing method error when public task form is updated + 2. More complete localisation dictionary + 3. JavaScript error on assignments filter page in IE8 has been covered + 4. Attachments are listed for notebook pages in mobile interface + 5. Covered issue with home screen and non-ASCII characters in widget titles + 6. Fixed issue where deleted financial managers kept receiving email + notifications even after they were deleted + 7. Email address can be re-used after original account is deleted + 8. Company name can be re-used after original company is deleted + 9. Billable status is properly displayed when time & expenses report is + printed (used to show all records as Non Billable) + 10. Object that don't implement IState could display deleted comments + 11. Project managers can assign tasks to all project members, not just to + members of their own company + 12. Source code properly displays file content + 13. Added attachments to notebook pages in mobile interface + 14. Fixed WebKit specific issue with Day Overview widget and user names that + contain non-ASCII characters + 15. Related time and expenses are dropped when item is removed from an + invoice via Edit Invoice form + 16. Fixed getting visible company ID-s + 17. activeCollab will check if email address is reserved by incoming mail + when new user is being created + 18. Improved Google Calendar compatibility + 19. Project Exporter stability is improved + 20. Completed milestones that have no open tasks are displayed as 100% done + 21. List of to do lists is properly updated when new to do list is created + 22. Max length of file in Documents section increased to 150 characters + 23. Exceptions in incoming mail will not choke frequently task, but log the + error and allow for task to be completed + 24. vCard importer is no longer case sensitive when it imports companies + 25. Notebook pages list is refreshed when pages are reordered + 26. Patched FileVersion class so it uses IRoutingContext + 27. IDownloadImplemention will not fail with a fatal error if parent object + does not implement IRoutingContext + 28. Fixed potential fatal error in incoming mail class + +activeCollab 3.1.4 [2012/06/03] +================================================================================ + +Enhancements: + + 1. FORCE_ROOT_URL introduced (experimental) + 2. Improved the way incoming mail picks up message parts + 3. Added download button to shared files page + 4. Plain Text used by default in code snippet tool + 5. When categories in projects are deleted, objects that belong to that + category are now unlinked, not deleted + 6. Added Nudge and Reminder options to To Do Lists + 7. Move to Notebook has current notebook pre-selected + 8. activeCollab opens non-persistent MySQL connections by default + +Bug Fixes: + + 1. file_is_writable() is aware whether file exists or not + 2. Smarty reconfigured to be in auto-clean mode + 3. Fixed issue with invoice creation after upgrade from activeCollab 2.3.x + 4. Code snippets now properly display type icons + 5. Corrected date in comments on shared pages + 6. Fixed issue with Add to Projects tool + 7. System displays Recent Activities to user who is viewing his own profile + or to a project manager on user's profile page + 8. Fixed spelling error in recurring profiles + 9. Fixed invoice edit/add issue in case there is no defined Tax rates + 10. Archived and trashed users can't log in any more + 11. Members can track time and expenses on task level + 12. Calendar properly displays user assignments + 13. Corrected links for upgrading license in admin section + 14. Fixed issue with select company picker in quotes for users who are not + financial managers + 15. Save client visibility in quotes for users who are not people managers + 16. Select company picker takes care of companies that are visible to user + 17. SQL error triggered by Tasks model has been covered + 18. Due date was off by one day in some situations in subtasks section + 19. Dependency on Horde_String removed + 20. Link popup properly picks up selection when it has brackets + 21. Fixed download for PHP setups that automatically use GZIPed buffer + 22. Improved the way "Minor Revision" picker looks like in mobile interface + 23. Password reset fixed in mobile interface + 24. Corrected URL for PayPal Express production mode + 25. Custom payment fix for 1000 amounts + 26. Email address can contain capitalised letters + 27. Numerous tweaks to HTML sanitizer + 28. Corrected invoice creation when there are no tax rates defined + 29. Fixed Internet Explorer 8 bug on Roles & Permissions page + 30. Long project names go over icons on project overview page + 31. Notebooks page in Mobile Interface has been patched + 32. Enhanced basic file uploads to work properly in Chrome + 33. Active projects can be trashed + 34. Quotes are properly sent now + 35. Documents preserves file name when file is downloaded + 36. Fixed breaking home screen when user in day overview widget has + apostrophe or double quotes in name + 37. Fixed showing client company managers to people who are not allowed to + see those users + 38. Fixed routing error display in production mode + +activeCollab 3.1.3 [2012/05/26] +================================================================================ + +Bug Fixes: + + 1. Fixed upgrade issue that affects activeCollab 3.1.1 users + 2. Fixed allow_payments field type in invoices table + +activeCollab 3.1.2 [2012/05/25] +================================================================================ + +Bug Fixes: + + 1. Fixed an error in daily task caused by mailing log clean-up + 2. float_to_time() fix for integer input values + 3. Fixed PayPal Express payment for client company managers + 4. "Notebook" prefix removed from notebook titles + 5. Removed option to create new objects from archived milestones + 6. Fixed situations when invoices were not always connected with projects + that they are based on + 7. Fixed invoice draft deletion issue + 8. Built-in (en_UTF-8) is not editable via administration + 9. Fixed permanent project deletion + 10. Fixed issue with new file version upload + 11. Day and month names can be translated now + 12. Fixed issue when milestone could not be created if tracking module was + not installed + 13. Less agressive HTML cleaner + 14. Fixed problems where in some cases project slugs ended up with non-ASCII + characters + 15. Fixed error on Quotes page + 16. Issue with upgrade script 17 covered (it used to end the upgrade) + 17. Fixed issue with can_use_api permission upgrade + +Enhancements: + + 1. activeCollab forces IE to run in standard mode + 2. People on Project People page sorted by their name + 3. Link To does not replace selected text with target name + 4. Label added to project's details page + +activeCollab 3.1.1 [2012/05/21] +================================================================================ + +Bug Fixes: + + 1. Option to create new tasks, discussions etc removed from details page of + archived milestones + 2. Fixed issue with subscribe / unsubscribe options on archived objects + 3. "$invoker not defined" JavaScript error fixed + 4. Scroll bar for invoices that have more than 7 items + 5. Fixed task counter and progress calculator for milestones + 6. Fixed issue with project icon change + 7. Fixed to do list filtering + 8. Notebook page preview fixed + 9. Option name for Pin option in Global Documents section + 10. HTML cleaner improved + 11. Installer and upgrade script now check whether config/version.php is + writable + 12. Subscription tweak for objects created with an email + 13. Admin Tools are displayed to administrators even when system is not in + development mode + 14. Completed On filter issue fixed in assignments filter + +Enhancements: + + 1. Fixed title for login page + 2. Client details added to Project at a Glance page + 3. Download option highlighted for Global Documents + 4. Completed items are crossed over in calendar view + 5. Various sharing improvements + 6. New icon for Rebuild Indexes administration tool + + +activeCollab 3.1.0 [2012/05/18] +================================================================================ + +Final stable activeCollab 3 release. Major new features and improvements: + + * All new interface brings faster navigation, less clutter and powerful + tools (navigate without refresh, object lists, great visual editor etc) + * activeCollab looks and works great on modern phones + * Outline and timeline view make project management much easier + * Tickets are renamed to tasks, checklists to to do lists and tasks to + subtasks + * Pages module renamed to Notebooks and significantly improved + * Configurable home screens with support for extension via modules + * Workweek and holiday configuration with smart assignment rescheduling + * Invoicing module now features invoice designer, quotes and payments + * Time tracking module has been extended with estimates and expense tracking + * Specify job type when tracking time. Each job type has its own hourly rate + * Set project budgets and see how project resources are spent, in real time + * Labels for projects and tasks enable easier status tracking and sorting + * Email integration offers email queue, email log and all new templates + * Incoming mail now supports definition of message filters + * Mail cleaner will remove quotes and signatures from replies + * Share project data with people who don't have an account in the system + * Powerful assignment filters and tracking reports + * GIT and Mercurial support added on top of SVN support to Source module + +... and much more. There's not a single section in activeCollab that haven't +been improved with this release, at least a bit! + +Enjoy! +activeCollab Team + +activeCollab 2.3.10 [2012/05/10] +================================================================================ + +Security: + + 1. Fixed SQL injection issue in project object class + 2. Fixed XSS issues with select users and select projects widgets + 3. Upgrade script steps can't be triggered without logging in as + administrator + + Thanks to http://www.stratsec.net/ for the report. + +Bug Fixes: + + 1. Project filter and group options could not be applied both at the same + time + 2. In project exporter corrected ticket ID numbers, links to tasks, added + time records from tasks to tickets and checklists + 3. Fixed missing project grouping options for some users having admin role + +Enhancements: + + 1. Backup restore instructions switched from a PHP file with a comment to a + text file + 2. Updated the list of file types whose source can be displayed + +activeCollab 2.3.9 [2012/03/21] +================================================================================ + +Security: + + 1. Fixed XSS problem with theme names (high) + 2. Added CSRF vulnerability check for editing password and company/role (medium) + 3. Secure flag is set to On for cookies when activeCollab uses HTTPS (medium) + 4. Login form does not re-print user password after failed authentication (medium) + + Thanks to Nokia and Nixu.com for the reports + +Enhancements: + + 1. Options menu can be toggled on click (was toggled on hover only) + +Bug Fixes: + + 1. Quick-fix for issue in TinyMCE when using backspace/delete in first item in an list + +activeCollab 2.3.8 [2012/02/09] +================================================================================ + +Licensing: + + 1. License agreement updated: http://www.activecollab.com/docs/manuals/licensing/license-agreement + +Enhancements: + + 1. Shipping latest stable TinyMCE release (v3.4.8), which now enables rich- + text editor to devices using iOS5 + 2. PHP 5.4 compatibility + +Bug Fixes: + + 1. Fixed problem with BenchmarkTimer class in CronController when system is + not in DEBUG mode + 2. Company invoices are listed on pages + 3. Only administrators can change role of another administrator + 4. Fixed error reports by Backup module + 5. Fixed issue with rich-text editor when activeCollab is used via mobile + interface + 6. Upgrade script does not enforce persistent connection + 7. Fixed JS "return false;" issue with IE 7 & 8 + 8. Output redirection bug fixed in Source admin section + 9. Missing 3rd parameter in Category::canAdd + 10. Fixed setting a project as favorite using drag & drop + +activeCollab 3.0.0 [2011/12/29] +================================================================================ + +First public activeCollab 3 beta release + +activeCollab 2.3.7 [2011/11/30] +================================================================================ + +Enhancements: + + 1. Users from archived companies are now excluded from the dialog for + adding users to a project + +Bug Fixes: + + 1. Escaped repository password + 2. Nested lists in visual editor are properly saved + 3. jQuery UI upgrade and IE drag and drop compatibility + 4. Fixed deleting project's icon + 5. Fixed few issues with print preview + 6. Fixed default date and time format issue for Windows + 7. If there is only one admin role, it's system or admin access cannot be + turned off + 8. Fixed the bug in the assignment filters, when pointing "completed on" + to a specific date and setting status "both active and open" actually + showed completed objects only + +activeCollab 2.3.6 [2011/11/01] +================================================================================ + +Enhancements: + + 1. Improved thumb.php + 2. People with manage permissions in specific section (discussions, files, + pages, tickets) can also manage categories in that section + 3. Removed extra database lock while emptying the trash + 4. If there are too many trashed objects, they will be deleted in chunks + (not all at once) + 5. Status updates now can be deleted + 6. Basecamp data importer included in Corporate and Small Biz builds + +Bug Fixes: + + 1. Fixed subscriptions page problem when project is empty + 2. Fixed permission checking for tasks assigned to a user who can't edit + parent ticket, checklist or a page + 3. Fixed favicon URL for login screen, as well as error page + 4. Fixed issue when assignments filter was including comments in the results + in some cases + 5. Fixed issue when trash was reporting to be empty and it wasn't + 6. Fixed bug where admins and project managers were being able to perform + search only across projects that they were added to + 7. Fixed PHP compatibility message for Incoming Mail and Importer modules + 8. Master categories at Admin page are now sorted in the same way as + they are sorted within projects + +activeCollab 2.3.5 [2011/09/16] +================================================================================ + +Bug Fixes: + + 1. Fixed PHP4 compatibility error in Subscriptions class + 2. Fixed Google Chrome issue with print preview stylesheets + +activeCollab 2.3.4 [2011/08/12] +================================================================================ + +Enhancements: + + 1. Favicon updated + 2. Directories having invalid name are excluded from modules list + 3. Objects can also be completed by using "completes" keyword in commit + messages + 4. Text excerpt adds white-space between paragraphs instead of "glueing" + them together + 5. Email notifications about new comments now include links attachments + (if any), and don't include parent object information block any more + 6. Admins and project managers can see all projects at projects list while + adding/editing an invoice + 7. Invoice number generator counters can now be manually set in admin panel + 8. Added character counter for status update message and blocking input when + the limit exceeded + 9. Ticket IDs are preserved upon creating a project from a template + 10. Tickets and tasks now use VEVENT instead of VTODO when exported in ICS + file type + 11. Improved recognition of Droid and Palm devices + 12. Improved Assignments by adding more options to filters + 13. Added "Reset password" to mobile interface + 14. Comments are now displayed as newest first; comment form moved above the + comments + 15. Added more recent activities on Dashboard and Project Overview + 16. Added "Subscriptions" link to user options and "My Subscriptions" to + project overview for easy subscription management + 17. Edit option for comments is locked one hour after the comment is posted + 18. No more "free for taking" tasks + + +Bug Fixes: + + 1. Fixed bug when eval() function throws an error while exporting projects + 2. Fixed bug with invoices where there was typo in one of the parameters in + Invoices class (condition instead of conditions) + 3. Fixed deadlock MySql issue - try 3 times before throwing an error + 4. Fixed warning message at parsing commit messages + 5. Fixed regex which was failing to validate URLs containing query string + (e.g. custom logout URL) + 6. Fixed editing "Issued on" value for invoices + 7. Fixed downloading files issue - ob_end_clean() + 8. Fixed subscribing project leader to tickets added via Quick Add + 9. Fixed pagination at company invoices page + 10. Checking for more error strings in Svn response + 11. Fixed selecting target project at resolving mail conflict + 12. Fixed viewing objects moved to other project via objects' old links. + 13. Fixed disappearing of assignment filters added to the group named "Other" + 14. Fixed setting wrong user and time for previous page version + 15. Fixed SVN issue when, on some systems, SVN repository always returns one + log even if there are no new ones + 16. Fixed calculating first day of the week that wasn't working as expected + in some cases + 17. Fixed error at mailbox add/edit page when neither Tickets nor Discussions + module are installed + 18. Fixed issue at checklists page when no tasks could be added + 19. Fixed displaying company users via API + 20. Some phrases were not available in the translation tool + 21. Fixed double status message posting + 22. Fixed default "Late" assignment filter showing completed objects + 23. Fixed issue when tasks rescheduled by a milestone were diplaying old due + dates + 24. Fixed issue when user with ability to manage an object couldn't manage + its subtasks + 25. Administrators and project managers can see all projects via mobile + interface now (before only projects assigned to) + 26. Fixed displaying 'Object' instead of selected date and date range in some + environments at assignment filter's details block + 27. Fixed showing all assignments instead of none, when selected company has + no users or no visible users + 28. Fixed print preview failing to load stylesheets in Safari 5.1 + 29. Fixed fatal error in setups using persistent connections but not having + them enabled on system level + + + +activeCollab 2.3.3 [2011/05/16] +================================================================================ + +Bug Fixes: + + 1. Fixed logo uploading in Company identity section of activeCollab + administration + 2. Email notifications when adding Documents + 3. Time reports now displays time records for anonymous users + 4. Fixed Go button on arhived ticket page + 5. Fixed problem with Page Version delete permissions + 6. Fixed importing language from xml issues when there's a translation for + one module only / translation for module has a single translation entry + 7. Fixed filemtime() PHP warnings when logo and avatar URL-s are returned + 8. Fixed PHP warning in ProjectPeopleController class + 9. Fixed bug with invoice unit price value while another language is chosen + where point (.) was interpreted as comma (,) thus preventing company + address to be rendered correctly + 10. Fixed bug for showing compare differences between revisions + 11. Fixed bug for time entries of deleted users when using project exporter + 12. Fixed bug to use "Use error output redirection" in Source Settings by + default + 13. Improved Internet Explorer 9 compatibility + +activeCollab 2.3.2 [2010/07/16] +================================================================================ + +Enhancements: + + 1. Only administrator can change password of another administrator + 2. TinyMCE upgraded + +Bug Fixes: + + 1. Fixed Source module bug (browse repository link error) + 2. Fixed Source module bug (update repository JS problem in IE) + 3. Change commits visibility on repository visibility changes + 4. Fixed MIME type issue with documents and attachments + 5. Ticket priority is properly set when ticket is created by incoming mail + 6. Fixed fatal error on status page when there are no status messages in the + database + 7. Fixed issue with task complete / reopen action in mobile interface + 8. Attachments can be deleted only by people who can edit parent object + 9. Only people who can see an object can subsctibe to it + 10. Fixed long URL problem with projects select widget when there's a lot of + projects to be excluded + 11. Fixed problem when system failed to connect time records with invoices + based on time reports + 12. Fixed problem with Styles menu in visual editor + +activeCollab 2.3.1 [2010/06/18] +================================================================================ + +Enhancements: + + 1. Added information on when the reminder was sent + 2. Added list of available modules to the welcome message + 3. Welcome message on the Dashboard is displayed only to Administrators + 4. Replies have been added to status module + 5. Copying/moving milestones to another project now allows copying/moving + all related objects (tickets, checklists, files, discussions) + 6. STDERR to STDOUT redirection (2>&1) in Source module's SVN commands is + now optional + 7. Added config option for limiting number of subscribers that are printed + on each page that lists them + 8. Source module can be accessed trough mobile interface + 9. Added message when a user who does not participate in any active projects + tries to download the .ics file + 10. Added --trust-server-cert option to Source module + 11. Added support for custom number of decimal spaces used in invoices, use + INVOICE_PRECISION in config.php to determine how many decimal spaces you + need. Maximum number of decimals supported by system is 3 + 12. Tax rate now can have 3 decimals + 13. Users on project's People tab are ordered by name + 14. Copy / Move to Projects lists all available projects to project managers + and administrators + 15. System sets Return-Path for outgoing messages + 16. Better canUnsubscribe() permission check for project objects + 17. Administrators, project managers and people managers can add people from + any company to projects + 18. Status updates module now supports replies to individual messages + 19. User has an option to avoid sending notification to company specified on + an invoice when adding last invoice payment + 20. Now the following fileds can be set through the API for project objects: + created_on, created_by_id, created_by_name, created_by_email + +Bug Fixes: + + 1. Source module is translatable + 2. Fixed problem with formatting of time data + 3. Fixed "With Selected ..." button style + 4. Improved edit time record form + 5. Fixed problem with pagination not remembering selected category in + Documents module + 6. Fixed problem with relation between milestones and checklists being lost + when project is created from a template + 7. Fixed bug with callback functions of modal dialogs + 8. Fixed issue with converting uppercase hyperlinks + 9. Fixed incorrect date for "last comment on" for discussions copied from + other projects + 10. Fixed bug that was crashing invoicing module when there is invoice which + is issued to the company which is deleted + 11. Fixed bug with invoicing module in which two or more invoices can share + same timerecords attached to them. From now on, when you assign + timerecord to one invoice, it can't be assigned to invoices created + afterwards + 12. Fixed diff/compare/history issue that affected some files in Source + module + 13. Fixed bug with number rounding in invoicing module + 14. Fixed bug with corrupted archives while using project exporter on some + installations + 15. Fixes for uploaded files permission and for cache file permission. File + permission can be overridden now with simple config option + 16. Fixed incorrect hidden input value when editing documents + 17. Fixed problem with long MIME type strings + 18. Warsaw moved into a correct time zone + 19. Fixed issue when long user agent string could cause query error when + MySQL is in strict SQL mode + 20. Improved PHP 5.3 compatibility + 21. All projects are listed in projects archive to administrators and project + managers when viewed by client + 22. Fixed missing argument warning in on_project_overview_sidebars handler + 23. Correct page version author is displayed on Pages tab + 24. Mobile interface now displays login error messages + 25. Fixed bug, when visitor receives 'Page not found' error when visiting + assignments page after deleting default assignments filter + 26. Fixed issue with logo resizing in invoicing administration + 27. Single quote (') is now allowed in email addresses + 28. Fixed issues with tr_TR locale + 29. Fixed issue with visual editor when caret gets moved to the beginning of + the editor after pasting text + 30. Removed completed objects from the project calendar iCal feed + 31. Visual editor disabled for mobile browsers (most of them do not support + content editable, or iframe design mode) + 32. Company name is 'cached' in invoice in case that company gets deleted + 33. Fixed issue where on some activeCollab setups if you try to download + PDF version of invoice, you receive fatal error message. + 34. Pinned projects list only projects that user is member of + 35. System does not allow last system administrator to change his system role + to a role which does not have administrator permissions + 36. Fixed issue with archive and RSS icons in status updates dialog + 37. Listing files in /work folder with browser is now disabled + 38. Installer sets COOKIE_DOMAIN to empty value in case of localhost + 39. Fixed problem when "Upload Now" on Files tab could not be translated + 40. Added stripos() for PHP4 compatibility + +Security: + + 1. Fixed potential XSS problem in SVN commit messages + 2. Fixed module, action and controller variable validation + (problem reported by Jose Carlos de Arriba) + +API Changes: + + 1. Status messages now return the URL of the user's avatar + 2. Added 'system_edition' field to /info command + 3. Added /projects/:project_id/files/categories call + 4. Added /projects/:project_id/discussions/categories call + 5. Added /projects/:project_id/tickets/categories call + 6. Added /projects/:project_id/pages/categories call + 7. Category filtering for tickets, pages, discussions and files + +activeCollab 2.3 [2009/10/09] +================================================================================ + +Enhancements: + + 1. Better option names on export project page + 2. Email address that is already in use by an user account can't be used for + incoming mailbox + 3. Clicking user's name in the list of commits in the Source module leads to + the list of commits made by that user + 4. Manage invoices permission management added to Invoice module page + +Bug Fixes: + + 1. Fixed problem when thumbnails are not loaded when warnings are on in + PHP 5.3.0 + 2. Stripped style comment from text when text is pasted from Microsoft Office + application (Word, Outlook etc) + 3. Time reports do not ignore time from deleted users any more + 4. Link to user profile from Source module now follows the way all other + URLs are formed + 5. Fixed issues when project icons, client logos and user avatars smaller + than 40x40px ended up with black background when resized + 6. Fixed issue with mobile interface on pages with categories and project + groups on setups with PATH_INFO_THROUGH_QUERY_STRING turned on + 7. Fixed print preview crashes in Internet Explorer + 8. admin_access and project_management permissions now override + can_see_private_objects permission + 9. New Company option removed from client picker on New Invoice form + 10. Fixed problem with number formatting + 11. Fixed bug when milestones got wrong dates on exported project + +activeCollab 2.2.2 beta [2009/09/29] +================================================================================ + +Enhancements: + + 1. Source module has the ability to set custom 'config-dir' for Subversion + +Bug Fixes: + + 1. Fixed PHP4 compatibility problem in PdfSettingsAdminController class + 2. Fixed 'duplicate entry for key...' in Source module + 3. Fixed bug on page with invoices listing where instead total price with + tax, price without tax is shown + 4. Fixed number rounding issue on 'Add Payment' page of Invoicing module + 5. Issued invoice now can be edited + 6. When creating invoice based on ticket and project time report, project + field on invoice form is preselected + +activeCollab 2.1.4 [2009/09/28] +================================================================================ + +Enhancements: + + 1. When an assignment is re-assigned, new assignees are automatically + subscribed to it + 2. All project template categories are copied to a new project + 3. Milestone information is included in email notifications + 4. DST setting now supports "-- System Default --" value on user profiles + 5. Emails sent from people who don't have access to certain incoming + mailbox, now can be manually imported while preserving original author + 6. PCRE (Perl-Compatible Regular Expressions) is required extension + 7. Added GMT -4:30 time zone + 8. XML extension has been added to optional, but recommended extensions list + 9. System will not throw a warning if PHP works in safe mode when it tries + to set default timezone to GMT + 10. Added option to filter archived projects by status + 11. When email is imported it updates last activity time in profile of the + user who created it + 12. Fixed PHP5.3.0 preg_quote() compatibility issue + +Bug Fixes: + + 1. Section labels used in select project permissions block now can be + translated + 2. Fixed problem where Quick Add time record form could not processed time + in 3:30 format + 3. Fixed problem where related tasks were not properly rescheduled when + parent milestone was rescheduled + 4. HTML entities are not double escaped in ticket titles + 5. Fixed issue with image visibility in Documents for non-admin users + 6. Fixed bug in mobile interface when using pagination on some installations + 7. Android based mobile devices now use interface made for iPhone devices + 8. System "system_access" permission can't be removed any more from the last + admin role + 9. Title of dialog window for changing avatars/logos/icons is now using + distinct text, instead of "Change icon" for all three of them + 10. After switching the language in user settings, confirmation message is + no longer displayed in previous language + 11. Fixed localization issue with New Task activity log entries + 12. Fixed problem with Unicode tags + 13. Download file links force download + 14. User can set due on date when creating ticket via quick add dialog + 15. Fixed who can see private document message + + +activeCollab 2.2.1 beta [2009/07/20] +================================================================================ + +Enhancements: + + 1. Added default logo for PDF invoices generated by invoicing module + 2. Improved the way activeCollab works with user sessions + 3. Cookie domain is configurable (if needed) + +Bug Fixes: + + 1. Fixed broken 'New Invoice Form' in IE6 and IE7 + 2. Tax Rate names in invoicing are not unique anymore + 3. Invoice can be issued only to company managers + 4. Predefined item template is not truncated anymore + 5. Source module notification e-mails include commit details (if there are + 10 or less commits in an update) + 6. Fixed bug in Source module when trying to view objects that were removed + from a repository + 7. Repositories from non-active projects are excluded from updating + 8. Fixed switching revisions in Source module + 9. "SVN executable not found" replaced with message that is being returned + from svn/command line + 10. Fixed PHP5.3.0 preg_quote() compatibility issue + +activeCollab 2.1.3 [2009/07/16] +================================================================================ + +Enhancements: + + 1. Added auto-reconnect for situations when MySQL closes connection in the + middle of the request + 2. Added new config options for better controlling the way mailing is + working (native mailer and marking messages as bulk options) + 3. System permission 'manage_trash' has been added + 4. Administrators and project managers see all objects that are in the Trash + 5. GZIP compression for assets (js, css and print collector files) can be + turned off by setting COMPRESS_ASSET_REQUESTS option to false in + config.php file + 6. {title} accepts language parameters just like {lang} does + +Bug Fixes: + + 1. Fixed fread() problem in collector files + 2. HTML Purifier now uses /cache folder to cache definitions + 3. Styles in visual editor are translatable + 4. Time records API returns same records as web interface + 5. Fixed notice in DashboardController + 6. Many localization fixes and tweaks (thanks to Frederik Sauer) + 7. Welcome message after user login is now in user's language + 8. Fixed problem when, in some rare cases, task parent form was loaded when + tasks was created with AJAX request + 9. Aligment of 'Complete ticket with this comment' checkbox fixed + 10. Empty Return-Path turned off by default + 11. Uppercase letters can be used in email addresses + 12. Fixed infinite visual editor explanding in Google Chrome + 13. Fixed issue where on some installations, incoming mail was treating first + empty line in the imported email, as beginning of hidden email history + +API Changes: + + 1. Comments now return list of files attached to them + 2. Fixed problem with Pages category not listing pages in API response + +activeCollab 2.2 beta [2009/06/25] +================================================================================ + +Enhancements: + + 1. Introducing Invoicing module in Corporate version (beta!) + 2. Introducing Source module in Corporate version (beta!) + +Bug Fixes: + + 1. Fixed fread() problem in collector files + 2. HTML Purifier now uses /cache folder to cache definitions + 3. Styles in visual editor are translatable + 4. Time records API returns same records as web interface + 5. Fixed issue with visual editor auto-expaner in Google Chrome + +activeCollab 2.1.2 [2009/06/13] +================================================================================ + +Enhancements: + + 1. Archive link in Projects is now aware of selected client and group + 2. HTML Purifier upgraded to version 2.1.5 (last PHP4 compatible version) + 3. Only people with manage permissions in Time section will see mass edit + checkboxes and controls + 4. Scheduled Tasks page now includes instructions for executing scheduled + tasks using PHP command line interface + 5. Billable status is automatically set to Yes in quick add dialog + 6. Added links to upgrades in Administration > System Information block + 7. People now see companies that are set as clients for a project even when + members of that company are not involved in a project + 8. Task notifications include link to parent object (ticket, checklist etc) + 9. Status module page with easy to access permissions added + +Bug Fixes: + + 1. Fixed buggy quick add dialog behavior + 2. Language importer is now more careful when importing languages from + broken xml + 3. Backup module on some installations was sorting previous backups by + their modification time instead of creation time + 4. Long links in Page diffs could make the diff block too wide and break the + layout in Safari + 5. Fixed issue with date filter for assignment filters + 6. Fixed project icon caching issue when project client is changed + 7. Fixed problem where projects with owner company set as a client are not + considered internal + 8. Fixed project exporter chrashing on some servers with PHP installed as + ISAPI on IIS + 9. Fixed time record creation / upgrade problem on some installations + 10. The last administrator in the system cannot disable "admin_access" + permission for his role + 11. Add links on milestone details page are aware of permissions now + 12. Fixed project exporter issue where attachments to pages and discussions + were not exported + 13. Fixed time reports that in some cases did not properly calcualte total + time if there was 1000 or more hours logged + 14. Email address validation now supports something+something@something.com + addresses + 15. Fixed iCalendar feed generation on PHP 5.0.x versions + 16. When user tries to delete a document from Documents section he will be + asked to confirm the action + 17. Bugfix for Safari 4 which was causing textarea to be stretched vertically + on page scroll + 18. Fixed automatic URL conversion bug that was introduced in v2.1.1 + 19. Object can't be restored if its parent is still in Trash + 20. Fixed issue with client tabs when projects are grouped by client + 21. Upgrade script did not properly update parent type for some attachments + 22. Fixed issue with deleting company logos, project icons, and user avatars + in dedicated pages + 23. Fixed problem with mass edit of time records in IE8 + 24. Fixed layout issues with popup dialogs in IE6 + +activeCollab 2.1.1 [2009/05/19] +================================================================================ + +Enhancements: + + 1. Increased number of comments per page to 25 + +Security: + + 1. Fixed XSS problem when error dump is displayed + 2. Fixed possible path exposure in error dumps + +Bug Fixes: + + 1. Object types in quick add module now are properly translated + 2. Fixed scrolling in quick add popup + 3. Covered some phrases that were not available for translation + 4. Added option in incoming mailbox add/editing form, to accept emails from + registered activeCollab users which are not added to project specified + in that incoming mailbox + 5. Fixed issue with restoring backups, when some users were having "Access + Forbidden" issues + 6. Fixed project description bug in mobile interface + 7. Fixed issues with incoming mail MIME encoding problem + 8. Fixed issue with quick add dialog, when it breaks apart when there is + more than ~10 projects + 9. Title of new company dialog was not properly named + 10. Fixed link auto discovery when link is at the beginning of the sentence + 11. Status updates in RSS now have valid permalinks + 12. Fixed ordering of backups in administration + 13. Incoming Mail is configured not to accept auto-responder emails + 14. Task priority is visible now + 15. Fixed password issue when new user is created with API command + 16. Fixed error display when DEBUG level is not set for development + 17. Fixed pre_var_dump function to properly clean variable dumps + 18. Fixed All Attachments permissions problem + +activeCollab 1.1.6 [2009/05/19] +================================================================================ + +Enhancements: + + 1. RSS feeds validate + 2. When clicking on New Ticket button while in ticket category, that category + will be preselected in Category drop-down on New Ticket form. + 3. Added description below project template picker which explains who will + be automatically added to the new project. When project is created from a + template, users will be imported from a template. If no template is + selected, users will be added based on auto-assignment settings. + 4. Anyone assignment filter returns task by ignoring assignment data. Now it + really returns tasks assigned to anyone. + 5. Not assigned assignment filter return tasks that do not have people + assigned to them. + 6. Status filter lets you define if you wish to have all, only active or only + completed tasks listed. + 7. Next page link at the bottom of Assignments page added. + +Security: + + 1. Fixed XSS problem when error dump is displayed. + 2. Fixed possible path exposure in error dumps. + +Bug Fixes: + + 1. Fixed pubdate bug in RSS generation. This cause problems with some RSS + readers because correct name of element is pubDate. + 2. Fixed problem with calendar popup in date picker being cut off in some + cases on 1024x768 resolutions or smaller. + 3. Fixed Internet Explorer print style switcher issue which caused problems + when print stylesheet was loaded for the second time. + 4. Removed Image Browser tab in Insert image tool. This feature was never + implemented and the tab caused a lot of confusion. + 5. Fixed error when edit time record form was submitted with validation error. + 6. Fixed bug with avatar / logo / project icon upload on some systems which + return false when we use is_file() for uploaded files. + 7. Fixed problem with Select Users dialog when there was a lot of users on + Internet Explorer 6. + +API Changes: + + 1. Fixed issue where discussion request did not return discussion comments. + +activeCollab 2.1 [2009/04/29] +================================================================================ + +Final stable activeCollab 2 release. Major new features and improvements: + +New Module - Incoming mail + + 1. activeCollab can check and import email. New messages are imported as + tickets or discussions, while replies to notifications are posted as + comments. Email attachments are imported as well + 2. Define any number of POP3 / IMAP servers to receive emails + 3. Detailed activity log to spot and resolve errors and conflicts + +New Module - Documents + + 1. Global documents section is perfect for common company documents, + operation manuals etc + 2. Post text or upload files + 3. Just like tickets, discussions or files, documents can be marked as + private and visible just to a specific group of people, while invisible to + other users + +Pages Module Overhaul + + 1. Page categories for better organization + 2. Compare version tool outlines changes between two versions of the page + 3. Easy reordering and regrouping of pages + 4. Page can be reverted to any version at any time + 5. Pages tab shows recently updated documents grouped by date when last + change was made + +Improved tasks and checklists + + 1. Drag and Drop reordering for tasks in checklists, pages and tickets + 2. Drag and Drop reordering of checklists + 3. Checklist page lists all checklists and their tasks. No need to go to + checklist details page to manage tasks + 4. Improved task creation workflow + +Improved Dashboard and Project Overview + + 1. New and improved activity log + 2. List of active projects shows all of your active projects + 3. Block that shows who was active in the last 15 minutes + 4. Project Overview now shows people involved with that project + +Improved people section + + 1. Friendlier interface makes navigation and management of people much easier + 2. User can be added to multiple project at once + 3. Improved New User form. By default it asks only for data it requires, but + you can execute advanced actions if needed + 4. Welcome messages can be sent to users at any time + 5. Client companies you no longer work with can be archived. Members of + client companies are no aware that their company is archive even if they + visit the system + +Other system improvements + + 1. Subscribing and notifying people is more obvious because picker is listed + right on the form instead in the popup + 2. Notifications sent by the system are more readable and contain more + information + 3. Easier management of categories, project groups and document groups + 4. Easier subscription management + 5. New version and better integration of visual editor. Images can be + uploaded directly from the editor + 6. Easier change of avatars, logos and project icons + 7. Test connection tool for mailing settings for easier troubleshooting + 8. Better module installation process + 9. Maintenance mode + 10. Easier translation management with XML import and export of language files + 11. Default assignment filter can be specified both globally and per user + +and many, many more changes. + +activeCollab 2.0 [2009/02/06] +================================================================================ + +First activeCollab 2 beta release (for complete feature set, check 2.1 release) + +activeCollab 1.1.5 [2008/12/01] +================================================================================ + +Enhancements: + + 1. People can be moved from one company to another. + 2. Added confirmation dialog when permanently removing objects from trash. + 3. Max upload size is displayed on upload files form. + 4. Time reports can be created from Reports section inside of projects. + 5. People manager cannot promote person into administrator. Only + administrators can do that. + 6. User's role cannot be changed if he or she is the last administrator in + the system. + 7. Added visibility indicator to Pages module. + 8. When JavaScript is disabled, system will display error message alerting + the user about it. This warning can be turned off by setting + WARN_WHEN_JAVASCRIPT_IS_DISABLED to false in config/config.php. + 9. Added a page that provides instructions how to enable JavaScript in + Microsoft Internet Explorer, Mozilla Firefox and Apple Safari. + 10. iCalendar feed added on user Schedule pages. Only project managers can use + these feeds. + 11. Pending Payment status added to Time Records. There is no interface for + this status, but it can be used by modules which control time record + status (Invoicing tools for example). + +Bug Fixes: + + 1. Fixed the issue where Select Users popup is not working on New / Edit + Assignment Filter and New / Edit Time Filter forms. + 2. Fixed the issue where successive milestones are extracted based on updated + due date instead of original value. + 3. Long file names are trimmed to 40 characters on Files tab. Extremely long + file names could break interface previously. + 4. Fixed problem where Project Starts On is sometimes off by one day due to + time-zone miscalculation. + 5. If a user assignees only himself to an object, project leader now will + also be subscribed to that object, automatically. + 6. Milestone moved to another project was preserving the relations to its + child objects in the project that it has been moved from. + 7. No error/success messages were displayed after turning the cache off. + 8. If a user had only last name entered in his profile, his e-mail address + was used in assignees block. + 9. Links were not automatically converted to be clickable in ticket body, + milestone description and project overview. + 10. Fixed 'Can't copy image to work path' error upon pressing Submit with no + file selected at edit project icon, edit avatar and edit company logo + pages. + 11. Fixed problem where objects couldn't be associated with milestones in + activeCollab setups with large amount of data. + 12. Corrected the problem with displaying "unknown project" in ticket history + after moving a ticket to another project. + 13. Fixed bug where, in some cases, ago modifier returned Yesterday for + actions that happened the day before Yesterday.. + 14. Date selected by default in time popup now properly calculates user's + time-zone. + +API Changes: + + 1. In time management calls, billable_status was added. is_billable and + is_billed are left for compatibility reasons, but are consireder + deprecated. + + +activeCollab 1.1.4 [2008/10/06] +================================================================================ + +Enhancements: + + 1. Object can be copied in parent project. + 2. Ticket time shows total time logged for ticket and all of its tasks. + 3. Improved time popup. + 4. Notify Assignees checkbox removed. Assignees will always be notified. + 5. Person creating a ticket, milestone, tasks, file, discussion or page will + be automatically subscribed to it. + 6. Project section included when visiting comment, tasks, attachment and + subscription pages. + 7. When tasks / ticket / milestone is re-assigned, notification is send to + all old and new assignees except the person who did the update even if + that person is one of the assignees. + 8. When user posts a comment he or she is automatically subscribed to object + that was commented. + 9. Project leader is automatically subscribed to tickets created with Public + Submit module. + 10. In New Task form priority and due date fields are hidden by default. + 11. User's project role is displayed on People project tab. + 12. If there are no assignees / subscribers selected when object is created, + project leader will be automatically subscribed and notified. + 13. Scheduled tasks administration page shows time when was the last time + scheduled tasks were executed (if ever). + 14. Comments on tickets, discussions, pages and files can be locked. + 15. Discussions can be pinned to the top of discussions list. + 16. Added support for servers that do not properly handle path info (some + versions of IIS for example). + 17. Improved underlying Status module code. + 18. System and license information displayed on administration start page. + 19. Upload files form now returns more descriptive error messages. + 20. Project Exporter uses built in notifications instead of custom div-s. + 21. Daily, hourly and frequently tasks executed through command line do not + display output unless there are errors to be displayed. + +Bug fixes: + + 1. Security fix! Instructions for restoring backup are stored in PHP file + instead of plain text file. + 2. When object is copied in another project milestone ID is reseted if no + milestone map is present. + 3. When ticket is copied it will use next available ticket ID in destination + project instead of keeping ID from original project. + 4. Duplicate subscriptions bug resulted by incomplete cleanup routine fixed. + 5. Fixed subscription caching issues when subscribe_users() method is called. + 6. Fixed problem with HTTP status code not being properly passed when error + page is displayed. + 7. Module info loading bug fixed. + 8. Master Categories will not let you define category names shorter than 3 + letters. + 9. Fixed problem where duplicate notifications are sent to users when + reminder was sent to people involved in a discussion. + 10. Fixed caching issue when module is uninstalled. + 11. Project Exporter exports completed milestones. + 12. Fixed issue where links to modules that user selected not to export are + still present in navigation. + +API improvements: + + 1. /roles/system - List all system roles (permissions included). If user is + not system administrator or people manager only default role ID is + returned! + 2. /roles/project - List all project roles (permissions included). No + permission checking is done. + 3. /role/:role_id - Show details of any role. No permission checking is done. + 4. Implemented support for work with project groups through API. + 5. New user fields: is_administrator, is_project_manager and + is_people_manager. + 6. Project people request (/projects/:project_id/people) returns more + information including users role and permissions for every project user. + 7. /projects/:project_id request now includes logged_user_permissions field + with role of currently logged user and his or hers permissions on a + selected project (similar to project people permission information). + 8. Assignee information is included in Ticket, Task and Milestone details. + 9. API for Status message - /status for listing and /status/add for + submitting messages. + 10. avatar_url property added for User details request. + 11. logo_url property added for Company details request. + 12. icon_url property added for Project details request. + 13. Permissions array added to every project object details response with + following permission values: can_edit, can_delete, can_change_visibility, + can_movecan_copy and can_change_complete_status. + + +activeCollab 1.1.3 [2008/08/12] +================================================================================ + +Enhancements: + + 1. Objects can be moved / copied only by administrators, project managers and + project leaders. + 2. Next page link on Projects, People, Files, Tickets, Discussions, Time, + Dashboard and Status archive pages. + 3. Improved notification message for private objects. + 4. If attachment is private it is indicated with red dot on Files tab (as for + Files). + 5. Calendar subscription link added to Project Calendar page. + 6. File description included in list of files on Files tab. + 7. Mass change ticket visibility added to tickets page. + 8. Links are recognized in text and automatically made clickable in comments. + 9. When time record is submitted through Quick add dialog Project and Is + billable values are preserved. + 10. Caching for project icon URL-s. + 11. System notifies user if he is viewing trashed object. + 12. Prettier notifications for private and trashed objects. + 13. HTMLPurifier can be turned off by adding define('PURIFY_HTML', false); to + config/config.php file. + 14. On New User form Password field is automatically focused when user selects + to specify password. + +Bug fixes: + + 1. Last file revision is not required to be instance of User class in order + to be returned. It can also be an AnonymousUser. + 2. First field on reset password form is password field instead of text + field. + 3. Completed, canceled or paused projects that project manager or + administrator is not directly involved with are now visible in project + archives. + 4. Fixed problem where milestone start and due dates can be one day of in + some cases. + 5. Fixed problem with users last activity time logging and display. + 6. Helper that shows which action was done by whom now uses a timezone + settings of logged in user to display proper time. + 7. Due helper ignores timezone settings when displaying due date tooltip + (correct behavior). + 8. JavaScript confirm dialog for Remove User option on role details page. + 9. Is billable is set to Yes by default in Quick Add dialog. + 10. Fixed problem with tickets archive no remembering selected category for + pagination. + 11. Fixed bug where pagination does not remember parent object when listing + time records attached to task or a ticket. + 12. One day shift for milestones fixed. Calendar applications do not include + DTEND day so it needs to be set to the day after due date. + 13. Fixed problem where not billable records are not counted correctly in time + reports. + 14. Parent page select box does not list page that is being updated and its + sub-pages. + 15. Fixed problem where attachments always inherit author from parent object + instead of using logged user. + 16. Fixed problem where not all assignees are properly moved into a project + created from template. + 17. Fixed broken image link to logo in error layout and on login / forgot + password pages in mobile interface. + 18. Fix for project icon not being displayed in Jump to Project dialog if it + was inherited from client. + +AP I improvements: + + 1. Added read_only flag to /info. Value of this flag will be 0 if API + supports both read and write requests and 1 if it supports only read + requests. + + +activeCollab 1.1.2 [2008/06/07] +================================================================================ + +Enhancements: + + 1. Removed Date time format field from profile. Instead of being a separate + configuration option it is now made out of date and time options + 2. Text input is automatically focused when status update dialog is displayed + 3. People who do not have can_see_private_objects permissions but can create + projects now do not have ability to select default visibility (Private + value will be set automatically) + 4. Object visibility indicator for tickets, discussions and checklists with + popup that explains who can see private objects + 5. Session ID is not force refreshed on every request + 6. Checkbox icons next to tasks user cannot complete are not clickable any + more + 7. If user does not have permissions to create tasks under a specific object + (ticket, page, checklist) New Task link is not displayed in Tasks section + header + 8. When breaking recent activities per day system now checks users timezone + instead of just using GMT value + 9. Ago helper now displays number of hours instead of Few hours ago + 10. Better localization coverage + 11. Backup module enhancements. It does not require specific MySQL + configuration any more but uses PHP to generate / restore SQL files + 12. Site logo and favicon graphics are now in septate folder so cannot + override them by accident when updating content of /assets folder + +Bug fixes: + + 1. Fixed problem with filtering time reports for a specific day + 2. Fixed some RSS / iCal feed links that were broken + 3. Fixed :project problem in select visibility control + 4. Script will die when CSV export is served + 5. Checklist tasks are available on assignments page + 6. Only people who can edit specific tickets can attach tasks to them + 7. Only people from a specific project can be reminded using Send Reminder + tool + 8. Fixed CSS/JS caching issues with Safari. + 9. Fixed upload issue for Windows host where slashes from uploaded file path + were stripped out + 10. Today / Late counter fixed + 11. Administrators, project managers and project leaders have edit / delete + object permissions no matter what. + 12. Fixed issue when time record is shown in project history even though user + does not have permissions to access time (access permission is by mistake + inherited from parent object) + 13. Fixed date format issues on Windows servers + 14. New discussion form does not lose message field when title is too short + and needs to be revised + 15. Fixed problem where attachment cannot be delete even though user has + permissions to edit parent object + 16. Fixed problem with first screen that needs point you to the installer, but + fails to do that on Windows + 17. Permissions cache is cleaned when role is updated or deleted + 18. Assignments cache is completely cleared when assignments of any particular + object are changed. + +API improvements: + + 1. Added logged user URL in /info call so you can see who the logged person + is for API key you are using + 2. Added type to all project objects in the system. This is especially + important when you list objects of mixed type + 3. Added /project/#project_id/user-tasks call that lists all tasks currently + logged user can work on in a particular project + +activeCollab 1.1.1 [2008/05/29] +================================================================================ + +Enhancements: + + 1. Projects are ordered by name in Quick add dialog + 2. More company fields included in API result for company request + 3. System will not allow you to submit an empty status message + 4. More descriptive select_visibility helper + 5. Turn on / off thumbnail creation for images (on by default) + 6. Limit max image size when thumbnail is created (default is 500kb) + +Bug fixes: + + 1. API is working properly with .htaccess hack for clean URL-s + 2. Send Reminders properly filters out people + 3. Dictionary does not exist error when create a new translation file has + been fixed + 4. Starred items from Trash are not counted on Dashboard + 5. Fixed problem with read / unread discussions + 6. When module is removed all reminders for old objects are also removed + 7. Time filtering by date range fixed + 8. Problem with Project Exporter module and open_basedir restriction has been + fixed + 9. Problem with filtering billable, but not billed hours fixed + 10. When project is created from template number of open / completed tasks and + project progress are refreshed + 11. Fixed problem when time record is added from time page for a particular + object + 12. HTTP errors for status update count asynchronous request fixed + 13. Fixed problem when user did not receive email notification in prefered + language + 14. Problem with members not being able to see their assignments fixed + + +activeCollab 1.1 [2008/05/19] +================================================================================ + +New modules: + + 1. Mobile access - Interface created just for mobile devices. iPhone support + included - you can finally touch activeCollab! + 2. Backup - automatically back up your database and files. + 3. Project Exporter - Export project data in series of static, HTML files + that does not require activeCollab to be displayed. Burn it on a CD, + upload to your website or send it to your clients. + 4. Public Submit - Let people submit tickets without logging into + activeCollab. CAPTCHA protection included. + 5. Status - Simple, Twitter like notifications system built right into + activeCollab. + +Time tracking improvements: + + 1. Reusable reports that work both globally and on project level. Reports can + list all time records or calculate how much time every user reported. + 2. Ability to mark billable time record as billed and filter it out in + reports. + 3. Time tracking for subtasks. + 4. New time widget makes it super easy to track time. + +Improved assignments page: + + 1. Powerful assignments filter that let you select not just your tasks but + tasks assigned to any company or group of people. + 2. RSS for any assignment filter. + 3. Ability to mark filter as private so only you can use it. + 4. Ability to mark task as completed directly on assignment page. + 5. Ability to subscribe to every task and receive email notification on + status change directly on assignments page. + 6. Track time for every ticket or subtask directly on assignments page. + +Calendar improvements: + + 1. Tickets and tasks are listed in calendar. + 2. Tasks, tickets and milestones can be marked as completed directly on + calendar page. + 3. Improved performance of calendar pages. + +Improved search: + + 1. Search for users. + 2. Search for project or inside of projects. + 3. Quick search dialog is really handy. It will show top 5 results directly + in the quick search dialog and give you link if you need more. + +Localization support: + + 1. Translate the interface in as many languages you want. + 2. Per user language settings. + 3. Email translates also support translations and are aware of user language + preferences. Every user will be notified in their preferred language. + 4. Per user date and time formatting settings. + 5. Administration tools for language management and translation. + +New permissions and roles: + + 1. Every user can have a system role now, not just members of owner company. + 2. Project roles are reusable sets of project permissions. Users can have + different roles in different projects. + 3. Per module access permissions. + 4. New system permissions - can add project, can see private objects and more + +File module improvements: + + 1. Attachments are listed in files listing. + 2. Thumbnails are created for images. + 3. Tool that lets you upload multiple files at once has been added. + 4. Improved workflow. + +API improvements: + + 1. Write support for API is added. + 2. API methods are documented. + 3. Configuration option that controls whether API is enabled or disabled. + This configuration option also lets you set up API to work in read only or + in read / write mode. + +Reminders: + + 1. Send reminders regarding a ticket, discussion or file to assignees, + subscribers, specific person or people who commented on it. + 2. Reminders include email notification and entry in �Things that require + your attention� block that is shown on dashboard. + 3. Read more about reminders in Developer Blog... + +Other changes: + + 1. Any project can be used as a template for new project. + 2. Auto-assignments system has been redone. + 3. Modules that are not required for system to work properly can be + uninstalled. + 4. Checklists module is not installed in Corporate version by default. You + can install it if you really need it. + 5. User password are not readable in database any more. + 6. System that detemines witch objects are new since your last visit is more + reliable now. + 7. When list of assignees is changed everyone is notified about the changes + (old and new assignees with complete list of changes). + 8. Links for creating new objects on milestone details page. + 9. Users last visit time is displayed on profile page. + 10. A simple tool for managing file, discussion and ticket categories that + are created when new project is created. + +Plus many, many more bug fixes and improvements! + +activeCollab 1.0.6 [2008/02/19] +================================================================================ + +Enhancements: + + 1. Improved role creation process + +Bug fixes: + + 1. Fixed project group duplication on projects page when logged in user is a + member of client company + 2. Fixed build script bug that resulted in empty names for initial set of + roles + +activeCollab 1.0.5 [2008/01/31] +================================================================================ + + 1. Problem with redirection on the project people page when there are no users + assigned to a project + 2. Files are sorted so the latest ones are on top + 3. Support for passing path_info through query string (for compatibility with + hosts such as Dreamhost) + 4. Assignments page is now displayed properly even when there are no projects + in the database + 5. When ticket is moved, the system will make sure to assign it an ID which is + not used in destination folder + 6. When ticket is moved, associated time records are also moved + 7. On the Projects page, only project groups where user has projects are + available + 8. Problem with email encoding + 9. Line breaks are preserved in discussion related email notifications + +activeCollab 1.0.4 [2007/10/30] +================================================================================ + +Features and Improvements: + + 1. Milestones start and end date can be the same day + 2. Members of client companies can track time (if they have proper + permissions) + 3. Added relation between files and milestones + 4. Added Manage Attachments button to comment options group (right to authors + name) + 5. Added Manage / Add links to Attachment and Subscription headers on object + details page + 6. Improved usability of comment options + 7. Added attachment field to New Discussion form + 8. activeCollab will keep connection alive by refreshing user session every 5 + minutes for as long as any activeCollab page is open + 9. When theme is updated in Administration it will be updated for all the + users + 10. When extracting task name system will use first 15 words instead of 5 + 11. Debug backtrace is saved only for fatal errors - saves some time on PHP4 + 12. Removed timezone information from date pickers + +Bug fixes: + + 1. Fixed issue where email notifications get cut off when containing + multibyte characters on some systems + 2. Fixed pagination on project page when browsing projects by company or by + group + 3. Proper project leader is selected on edit project page + 4. Fixes JavaScript and CSS issue for servers with zlib.output_compression + set to On + 5. Comments, Attachments and Tasks will properly inherit parents visibility + 6. Fixed issue with due display and calculation + 7. Fixed problem with HTML entities being escaped two times in the activity + logs + 8. Fixed problem when user cannot be subscribed to the object if he or she + was already a subscriber + 9. File backend cache uses PHP files instead of plain text files + 10. .htaccess that restricts direct access to files in /cache, /import, /logs, + /thumbnails and /upload folders added + 11. Multibyte operations are forcing UTF-8 encoding + 12. White is used instead of black when resizing images with transparent areas + 13. Fixed select_user helper so it does not break the script when data is out + of sync in database + 14. Pagination helper will render first page even when there are no items to + show (information that there are no items is displayed in that case) + 15. JavaScript error when selecting user or assignee fixed + 16. Better data cleanup on project deletion + +activeCollab 1.0.3 [2007/10/17] +================================================================================ + +Bug fixes: + + 1. Fixed the problem with time tracking module being too restrictive about + who can and who can't add time records + +activeCollab 1.0.2 [2007/10/16] +================================================================================ + +Features and Improvements: + + 1. Improved compatibility with Safari 2 + 2. Improved search results page + 3. Trash added to the Main Menu + 4. When project is created, user is redirected to Add People page + automatically + 5. Tasks without due date are not listed on Assignments page when ordered by + due date + 6. At Assignments page, due date is displayed next to the task creator + 7. When assignments are ordered by creation time, new column with creation + time is displayed + +Bug fixes: + + 1. Fixed problem with query string generation on PHP5 versions lower than + PHP 5.1.2 + 2. Fixed syntax error in HTML Purifier when trying to use DOMLex on latest + PHP 4 version, even though it is supported only in PHP5 + 3. Fixed Not Found issue with servers that do not provide good PATH_INFO + value + 4. Administrators and Project Managers can see all of the projects in P + rojects section + 5. No permission to remove / update user permissions on some systems + 6. No permission to remove / delete category + 7. Calendar displaying all tasks / tickets to the people not assigned to any + projects + 8. Add Timerecord permission enforced + 9. Files do not get attached to objects in PHP4 + 10. Mass mailer not sending emails + 11. JavaScript initialization after AJAX request on Trash / Starred page + +activeCollab 1.0 [2007/10/05] +================================================================================ + +Initial release \ No newline at end of file diff --git a/resources/lang/en/lang.php b/resources/lang/en/lang.php index 7adc58319..73252faf2 100644 --- a/resources/lang/en/lang.php +++ b/resources/lang/en/lang.php @@ -184,15 +184,17 @@ return [ | Company Settings Page |-------------------------------------- */ - 'company' => 'Company', - 'website' => 'Website', - 'phone' => 'Phone', - 'address' => 'Address', - 'landing' => 'Landing Page', - 'offline' => 'Offline Page', - 'thank' => 'Thank Page', - 'logo' => 'Logo', - 'save' => 'Save', + 'company' => 'Company', + 'website' => 'Website', + 'phone' => 'Phone', + 'address' => 'Address', + 'landing' => 'Landing Page', + 'offline' => 'Offline Page', + 'thank' => 'Thank Page', + 'logo' => 'Logo', + 'save' => 'Save', + 'delete-logo' => 'Delete logo', + 'click-delete' => 'Click here to delete', /* |-------------------------------------- | System Settings Page @@ -243,6 +245,15 @@ return [ 'attachments' => 'Attachments', 'email_attahment_user' => 'Email attachments to the user', 'cron_notification' => 'Enable Notification cron', + 'cron' => 'Job Scheduler', + 'crone-url-message' => "These are Faveo's Job Scheduler(cron job) url for your system.", + 'clipboard-copy-message' => 'Copied to clipboard.', + 'click' => 'Click here', + 'check-cron-set' => 'to check how to set cron jobs on your server.', + 'notification-email' => 'Email notifications', + 'click-url-copy' => 'Click here to copy URL', + 'job-scheduler-error' => 'Job scheduler can not be updated.', + 'job-scheduler-success' => 'Job scheduler updated successfully.', /* |-------------------------------------- | Ticket Settings Page @@ -280,6 +291,10 @@ return [ 'registration_method' => 'Registration Method', 'user_session_timeout' => 'User Session Timeout', 'client_quick_access' => 'Client Quick Access', + 'cron' => 'Cron', + 'system-settings' => 'System Settings', + 'settings-2' => 'Settings', + /* |-------------------------------------- | Auto-Response Settings Page @@ -405,6 +420,28 @@ return [ */ 'transient' => 'Transient', 'ticket_overdue_alert' => 'Ticket Overdue Alerts', + + /* + |-------------------------------------- + | Work Flow + |-------------------------------------- + */ + 'workflow' => 'Workflow', + 'ticket_workflow' => 'Ticket Workflow', + 'create_workflow' => 'Create Workflow', + 'edit_workflow' => 'Edit Workflow', + 'updated' => 'Updated', + 'target' => 'Target', + 'target_channel' => 'Target Channel', + 'exceution_order' => 'Exceution Order', + 'target_channel' => 'Target Channel', + 'workflow_rules' => 'Workflow Rules', + 'workflow_action' => 'Workflow Action', + 'rules' => 'Rules', + 'order' => 'Order', + 'condition' => 'Condition', + 'statement' => 'Statement', + /* |-------------------------------------- | Form Create Page @@ -754,6 +791,10 @@ return [ 'merge-error2' => 'Please select ticket to merge.', 'select-tickets-to merge' => 'select two or more tickets to merge.', 'different-users' => 'Ticktes from different users', + 'clean-up' => 'Clean up', + 'hard-delete-success-message' => 'Tickets have been deleted permanently.', + 'overdue' => 'Overdue', + 'change_owner_for_ticket' => 'Change Owner for Ticket', /* |------------------------------------------------ diff --git a/resources/views/notifications-all.blade.php b/resources/views/notifications-all.blade.php new file mode 100644 index 000000000..bff4bbb5a --- /dev/null +++ b/resources/views/notifications-all.blade.php @@ -0,0 +1,215 @@ +@extends('themes.default1.agent.layout.agent') + + +@section('Users') +class="active" +@stop +@section('HeadInclude') + +@stop +@section('user-bar') +active +@stop + +@section('user') +class="active" +@stop + + + +@section('content') +
    + @if(Session::has('success')) +
    + + Alert! Success. + + {{Session::get('success')}} +
    + @endif + + @if(Session::has('fails')) +
    + + Alert! Failed. + + {{Session::get('fails')}} +
    + @endif + +
    +
    + +
    +
    +

    Notification Page

    +
    + +
    + +
    + + + + + + +
    + + +
    +
      + @if(count($notifications)) + @foreach($notifications as $notification) + @if($notification->type == 'registration') +
    • + + + + + + + +
      + + +
      +
    • + @else +
    • + + +
      + + +
      +
    • + @endif + @endforeach + + @else +
    • + +
      No Notifications Available!
      + + +
    • + @endif + +
    +
    + +
    + + + +
    +
    + + +
    + +
    + +
    +
    + + +@stop \ No newline at end of file diff --git a/resources/views/themes/default1/admin/helpdesk/agent/agents/agent-profile.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/agents/agent-profile.blade.php index eda78e5b8..025562f92 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/agents/agent-profile.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/agents/agent-profile.blade.php @@ -1,14 +1,14 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') active @stop -@section('staffs') +@section('agents') class="active" @stop diff --git a/resources/views/themes/default1/admin/helpdesk/agent/agents/create.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/agents/create.blade.php index 4d64ec717..ababe4dd0 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/agents/create.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/agents/create.blade.php @@ -1,14 +1,14 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') active @stop -@section('staffs') +@section('agents') class="active" @stop diff --git a/resources/views/themes/default1/admin/helpdesk/agent/agents/edit.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/agents/edit.blade.php index 0b8d0e518..4bebb36dc 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/agents/edit.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/agents/edit.blade.php @@ -1,14 +1,14 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') active @stop -@section('staffs') +@section('agents') class="active" @stop diff --git a/resources/views/themes/default1/admin/helpdesk/agent/agents/index.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/agents/index.blade.php index 1eb51e93c..ff1944044 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/agents/index.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/agents/index.blade.php @@ -1,14 +1,14 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') active @stop -@section('staffs') +@section('agents') class="active" @stop diff --git a/resources/views/themes/default1/admin/helpdesk/agent/departments/create.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/departments/create.blade.php index c2b1b3449..a9c379bef 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/departments/create.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/departments/create.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/agent/departments/edit.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/departments/edit.blade.php index cfaed9684..9440fc0ef 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/departments/edit.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/departments/edit.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/agent/departments/index.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/departments/index.blade.php index d4741c5a3..f911461c3 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/departments/index.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/departments/index.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/agent/groups/create.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/groups/create.blade.php index ad6237a66..b165d6e2a 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/groups/create.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/groups/create.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') @@ -58,10 +58,10 @@ class="active" {!! $errors->first('group_status', ':message') !!}
    - {!! Form::radio('group_status','1',true) !!} {{Lang::get('lang.enable')}} + {!! Form::radio('group_status','1',true) !!} {{Lang::get('lang.active')}}
    - {!! Form::radio('group_status','0',null) !!} {{Lang::get('lang.disabled')}} + {!! Form::radio('group_status','0',null) !!} {{Lang::get('lang.inactive')}}
    diff --git a/resources/views/themes/default1/admin/helpdesk/agent/groups/edit.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/groups/edit.blade.php index b60d907d0..26813e345 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/groups/edit.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/groups/edit.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') @@ -60,10 +60,10 @@ class="active" {!! $errors->first('group_status', ':message') !!}
    - {!! Form::radio('group_status','1',true) !!} {{Lang::get('lang.enable')}} + {!! Form::radio('group_status','1',true) !!} {{Lang::get('lang.active')}}
    - {!! Form::radio('group_status','0',null) !!} {{Lang::get('lang.disabled')}} + {!! Form::radio('group_status','0',null) !!} {{Lang::get('lang.inactive')}}
    diff --git a/resources/views/themes/default1/admin/helpdesk/agent/groups/index.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/groups/index.blade.php index 1b8679264..e34c3565a 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/groups/index.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/groups/index.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/agent/teams/create.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/teams/create.blade.php index 925301542..2425b30f0 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/teams/create.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/teams/create.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/agent/teams/edit.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/teams/edit.blade.php index d1495682d..ca768fbc3 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/teams/edit.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/teams/edit.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/agent/teams/index.blade.php b/resources/views/themes/default1/admin/helpdesk/agent/teams/index.blade.php index e291a6197..a9b73cd28 100644 --- a/resources/views/themes/default1/admin/helpdesk/agent/teams/index.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/agent/teams/index.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Staffs') -class="active" +active @stop @section('staffs-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/emails/banlist/create.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/banlist/create.blade.php index 3580ef09a..32f6a2514 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/banlist/create.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/banlist/create.blade.php @@ -2,7 +2,7 @@ @section('Emails') -class="active" +active @stop @section('emails-bar') @@ -69,7 +69,7 @@ class="active" {!! Form::radio('ban',1) !!} {{Lang::get('lang.active')}}
    - {!! Form::radio('ban',0) !!} {{Lang::get('lang.disabled')}} + {!! Form::radio('ban',0) !!} {{Lang::get('lang.inactive')}}
    diff --git a/resources/views/themes/default1/admin/helpdesk/emails/banlist/edit.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/banlist/edit.blade.php index 2e9849e50..cdcefe86e 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/banlist/edit.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/banlist/edit.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Emails') -class="active" +active @stop @section('emails-bar') @@ -49,7 +49,7 @@ class="active" {!! Form::radio('ban',1) !!} {{Lang::get('lang.active')}}
    - {!! Form::radio('ban',0) !!} {{Lang::get('lang.disabled')}} + {!! Form::radio('ban',0) !!} {{Lang::get('lang.inactive')}}
    diff --git a/resources/views/themes/default1/admin/helpdesk/emails/banlist/index.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/banlist/index.blade.php index dec00a3a9..b87f15ea4 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/banlist/index.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/banlist/index.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Emails') -class="active" +active @stop @section('emails-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/emails/emails/create.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/emails/create.blade.php index 896de35a7..7463576bd 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/emails/create.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/emails/create.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Emails') -class="active" +active @stop @section('emails-bar') @@ -26,8 +26,7 @@ class="active" @stop -@section('content') - +@section('content')
    @@ -117,25 +116,30 @@ class="active"
    -
    +
    {!! Form::label('fetching_protocol',Lang::get('lang.fetching_protocol')) !!} {!! $errors->first('fetching_protocol', ':message') !!} {!!Form::select('fetching_protocol',['imap' => 'IMAP'],null,['class' => 'form-control select', 'id' => 'fetching_protocol']) !!}
    -
    +
    {!! Form::label('fetching_host',Lang::get('lang.host_name')) !!} {!! $errors->first('fetching_host', ':message') !!} {!! Form::text('fetching_host',null,['class' => 'form-control', 'id' => 'fetching_host']) !!}
    -
    +
    {!! Form::label('fetching_port',Lang::get('lang.port_number')) !!} {!! $errors->first('fetching_port', ':message') !!} {!! Form::text('fetching_port',null,['class' => 'form-control', 'id' => 'fetching_port']) !!}
    -
    +
    {!! Form::label('fetching_encryption',Lang::get('lang.encryption')) !!} {!! $errors->first('fetching_encryption', ':message') !!} - {!!Form::select('fetching_encryption',['none' => 'None', 'ssl' => 'SSL', 'tls' => 'TLS', 'ssl/novalidate-cert' => 'SSL (Accept all certificates)', 'tls/novalidate-cert' => 'TLS (Accept all certificates)'],null,['class' => 'form-control select', 'id' => 'fetching_encryption']) !!} + {!!Form::select('fetching_encryption',['none' => 'None', 'ssl' => 'SSL', 'tls' => 'TLS'],null,['class' => 'form-control select', 'id' => 'fetching_encryption']) !!} +
    +
    +
    If this checkbox is not checked SSL certificates will not be validated
    +

    +   Validate certificates from TLS/SSL server
    @@ -240,7 +244,7 @@ class="active" var sending_host = document.getElementById('sending_host').value; var sending_port = document.getElementById('sending_port').value; var sending_encryption = document.getElementById('sending_encryption').value; - + var validate = $('input#validate[type="checkbox"]:checked', this).val(); var filter_number = /^([0-9])/; var error_list = []; diff --git a/resources/views/themes/default1/admin/helpdesk/emails/emails/edit.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/emails/edit.blade.php index a98c6b4f5..e38914a6f 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/emails/edit.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/emails/edit.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Emails') -class="active" +active @stop @section('emails-bar') @@ -29,7 +29,6 @@ class="active" @section('content') - {!!Form::model($emails,['url'=>'','id'=>'form'])!!} @@ -49,11 +48,9 @@ class="active"
    - {!! Form::label('email_address',Lang::get('lang.email_address')) !!} {!! $errors->first('email_address', ':message') !!} {!! Form::text('email_address',null,['class' => 'form-control']) !!} -
    @@ -76,38 +73,33 @@ class="active"
    - {!! Form::label('department',Lang::get('lang.department')) !!} {!! $errors->first('department', ':message') !!} {!!Form::select('department', [''=>'--System Default--','departments'=>$departments->lists('name','id')],null,['class' => 'form-control select']) !!} -
    - {!! Form::label('priority',Lang::get('lang.priority')) !!} {!! $errors->first('priority', ':message') !!} {!!Form::select('priority', [''=>'--System Default--','Priorities'=>$priority->lists('priority_desc','priority_id')],null,['class' => 'form-control select']) !!} -
    - {!! Form::label('help_topic',Lang::get('lang.help_topic')) !!} {!! $errors->first('help_topic', ':message') !!} {!!Form::select('help_topic', [''=>'--System Default--','Help Topics'=>$helps->lists('topic','id')],null,['class' => 'form-control select']) !!}
    -
    {!! Form::label('auto_response', Lang::get('lang.auto_response')) !!}
    - auto_response == 1) { - echo "checked='checked'"; -} ?>> {!!Lang::get('lang.disable_for_this_email_address')!!} + auto_response == 1) { + echo "checked='checked'"; + } + ?>> {!!Lang::get('lang.disable_for_this_email_address')!!}
    -
    @@ -122,9 +114,11 @@ class="active"
    - fetching_status == 1) { - echo "checked='checked'"; -} ?>> {{Lang::get('lang.enable')}} + fetching_status == 1) { + echo "checked='checked'"; + } + ?>> {{Lang::get('lang.enable')}}
    @@ -132,25 +126,30 @@ class="active"
    -
    +
    {!! Form::label('fetching_protocol',Lang::get('lang.fetching_protocol')) !!} {!! $errors->first('fetching_protocol', ':message') !!} {!!Form::select('fetching_protocol',['imap' => 'IMAP'],null,['class' => 'form-control select', 'id' => 'fetching_protocol']) !!}
    -
    +
    {!! Form::label('fetching_host',Lang::get('lang.host_name')) !!} {!! $errors->first('fetching_host', ':message') !!} {!! Form::text('fetching_host',null,['class' => 'form-control', 'id' => 'fetching_host']) !!}
    -
    +
    {!! Form::label('fetching_port',Lang::get('lang.port_number')) !!} {!! $errors->first('fetching_port', ':message') !!} {!! Form::text('fetching_port',null,['class' => 'form-control', 'id' => 'fetching_port']) !!}
    -
    +
    {!! Form::label('fetching_encryption',Lang::get('lang.encryption')) !!} {!! $errors->first('fetching_encryption', ':message') !!} - {!!Form::select('fetching_encryption',['none' => 'None', 'ssl' => 'SSL', 'tls' => 'TLS', 'ssl/novalidate-cert' => 'SSL (Accept all certificates)', 'tls/novalidate-cert' => 'TLS (Accept all certificates)'],null,['class' => 'form-control select', 'id' => 'fetching_encryption']) !!} + {!!Form::select('fetching_encryption',['none' => 'None', 'ssl' => 'SSL', 'tls' => 'TLS'],null,['class' => 'form-control select', 'id' => 'fetching_encryption']) !!} +
    +
    +
    If this checkbox is not checked SSL certificates will not be validated
    +

    +   Validate certificates from TLS/SSL server
    @@ -165,9 +164,11 @@ class="active" {!! Form::label('sending_status',Lang::get('lang.status')) !!}
    - sending_status == 1) { - echo "checked='checked'"; -} ?>> {!! Lang::get('lang.enable') !!} + sending_status == 1) { + echo "checked='checked'"; + } + ?>> {!! Lang::get('lang.enable') !!}
    @@ -208,12 +209,9 @@ class="active"
    {!!Form::close()!!} - - - - @stop diff --git a/resources/views/themes/default1/admin/helpdesk/emails/emails/index.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/emails/index.blade.php index aa165bd71..4cc64e454 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/emails/index.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/emails/index.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Emails') -class="active" +active @stop @section('emails-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/emails/template/create.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/template/create.blade.php index 4c9a4c5cb..ad6a4e35b 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/template/create.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/template/create.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Emails') -class="active" +active @stop @section('emails-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/emails/template/edit.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/template/edit.blade.php index aecadebb1..cf00f5c08 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/template/edit.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/template/edit.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Emails') -class="active" +active @stop @section('emails-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/emails/template/formDiagno.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/template/formDiagno.blade.php index 3875f402d..8101b2f43 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/template/formDiagno.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/template/formDiagno.blade.php @@ -1,14 +1,14 @@ @extends('themes.default1.admin.layout.admin') @section('Emails') -class="active" +active @stop @section('emails-bar') active @stop -@section('diagno') +@section('diagnostics') class="active" @stop diff --git a/resources/views/themes/default1/admin/helpdesk/emails/template/index.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/template/index.blade.php index 572603421..de6cdd917 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/template/index.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/template/index.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Emails') -class="active" +active @stop @section('emails-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/emails/template/listdirectories.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/template/listdirectories.blade.php index fb92caca1..3c5b55d2b 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/template/listdirectories.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/template/listdirectories.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Emails') -class="active" +active @stop @section('emails-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/emails/template/listtemplates.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/template/listtemplates.blade.php index d2a28028a..fe2e9aea3 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/template/listtemplates.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/template/listtemplates.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Emails') -class="active" +active @stop @section('emails-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/emails/template/readtemplates.blade.php b/resources/views/themes/default1/admin/helpdesk/emails/template/readtemplates.blade.php index 5fc17123d..429757caa 100644 --- a/resources/views/themes/default1/admin/helpdesk/emails/template/readtemplates.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/emails/template/readtemplates.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Emails') -class="active" +active @stop @section('emails-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/language/create.blade.php b/resources/views/themes/default1/admin/helpdesk/language/create.blade.php index deef40748..86f1989e3 100644 --- a/resources/views/themes/default1/admin/helpdesk/language/create.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/language/create.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Settings') -class="active" +active @stop @section('settings-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/language/index.blade.php b/resources/views/themes/default1/admin/helpdesk/language/index.blade.php index d010a919e..3f6d68ed5 100644 --- a/resources/views/themes/default1/admin/helpdesk/language/index.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/language/index.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Settings') -class="active" +active @stop @section('settings-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/manage/form/create.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/form/create.blade.php index 98aeafa20..11b8ca408 100644 --- a/resources/views/themes/default1/admin/helpdesk/manage/form/create.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/manage/form/create.blade.php @@ -1,14 +1,14 @@ @extends('themes.default1.admin.layout.admin') @section('Manage') -class="active" +active @stop @section('manage-bar') active @stop -@section('form') +@section('forms') class="active" @stop diff --git a/resources/views/themes/default1/admin/helpdesk/manage/form/edit.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/form/edit.blade.php index c4ebb7ac9..09f8146fc 100644 --- a/resources/views/themes/default1/admin/helpdesk/manage/form/edit.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/manage/form/edit.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Manage') -class="active" +active @stop @section('manage-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/manage/form/form.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/form/form.blade.php index 4db9207cf..ce37916b9 100644 --- a/resources/views/themes/default1/admin/helpdesk/manage/form/form.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/manage/form/form.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Manage') -class="active" +active @stop @section('manage-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/manage/form/index.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/form/index.blade.php index 6164211f6..b288044ea 100644 --- a/resources/views/themes/default1/admin/helpdesk/manage/form/index.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/manage/form/index.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Manage') -class="active" +active @stop @section('manage-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/manage/form/preview.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/form/preview.blade.php index 3298ab2bb..eb348f778 100644 --- a/resources/views/themes/default1/admin/helpdesk/manage/form/preview.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/manage/form/preview.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Manage') -class="active" +active @stop @section('manage-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/manage/helptopic/create.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/helptopic/create.blade.php index 5b05e5603..16a63a03b 100644 --- a/resources/views/themes/default1/admin/helpdesk/manage/helptopic/create.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/manage/helptopic/create.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Manage') -class="active" +active @stop @section('manage-bar') @@ -52,9 +52,9 @@ class="active"
    {!! Form::label('ticket_status',Lang::get('lang.status')) !!}   - {!! $errors->first('ticket_status', ':message') !!} - {!! Form::radio('ticket_status','1',true) !!} {{Lang::get('lang.active')}}    - {!! Form::radio('ticket_status','0') !!} {{Lang::get('lang.disabled')}} + {!! $errors->first('status', ':message') !!} + {!! Form::radio('status','1',true) !!} {{Lang::get('lang.active')}}    + {!! Form::radio('status','0') !!} {{Lang::get('lang.inactive')}}
    @@ -92,7 +92,7 @@ class="active"
    - {!! Form::label('custom_form',Lang::get('lang.custom')) !!} + {!! Form::label('custom_form',Lang::get('lang.Custom_form')) !!} {!! $errors->first('custom_form', ':message') !!} {!!Form::select('custom_form', [''=>'Select a Form','Custom Forms'=>$forms->lists('formname','id')],1,['class' => 'form-control']) !!}
    @@ -139,7 +139,7 @@ class="active" {!! Form::label('auto_assign',Lang::get('lang.auto_assign')) !!} {!! $errors->first('auto_assign', ':message') !!} - {!!Form::select('auto_assign', [''=>'Select an Agent','Agents'=>$agents->lists('user_name','id')],null,['class' => 'form-control']) !!} + {!!Form::select('auto_assign', [''=>'Select an Agent','Agents'=>$agents->lists('first_name','id')],null,['class' => 'form-control']) !!}
    diff --git a/resources/views/themes/default1/admin/helpdesk/manage/helptopic/edit.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/helptopic/edit.blade.php index 6a24b4b6d..38004ae6f 100644 --- a/resources/views/themes/default1/admin/helpdesk/manage/helptopic/edit.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/manage/helptopic/edit.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Manage') -class="active" +active @stop @section('manage-bar') @@ -46,9 +46,9 @@ class="active"
    {!! Form::label('ticket_status',Lang::get('lang.status')) !!}   - {!! $errors->first('ticket_status', ':message') !!} - {!! Form::radio('ticket_status','1',true) !!} {{Lang::get('lang.active')}}    - {!! Form::radio('ticket_status','0') !!} {{Lang::get('lang.disabled')}} + {!! $errors->first('status', ':message') !!} + {!! Form::radio('status','1',true) !!} {{Lang::get('lang.active')}}    + {!! Form::radio('status','0') !!} {{Lang::get('lang.inactive')}}
    @@ -68,7 +68,7 @@ class="active" {!! Form::label('topic',Lang::get('lang.topic')) !!} {!! $errors->first('topic', ':message') !!} - {!! Form::text('topic',null,['disabled'=>'disabled','class' => 'form-control']) !!} + {!! Form::text('topic',null,['class' => 'form-control']) !!} @@ -85,7 +85,7 @@ class="active"
    - {!! Form::label('custom_form',Lang::get('lang.custom')) !!} + {!! Form::label('custom_form',Lang::get('lang.Custom_form')) !!} {!! $errors->first('custom_form', ':message') !!} {!!Form::select('custom_form', [''=>'Select a Form','Custom Forms'=>$forms->lists('formname','id')],null,['class' => 'form-control']) !!}
    @@ -106,8 +106,8 @@ class="active"
    {!! Form::label('priority',Lang::get('lang.priority')) !!} - {!! $errors->first('priority', ':message') !!} {!!Form::select('priority', [''=>'Select a Proirity','Priorities'=>$priority->lists('priority_desc','priority_id')],null,['class' => 'form-control']) !!} + {!! $errors->first('priority', ':message') !!}
    @@ -115,8 +115,9 @@ class="active"
    {!! Form::label('sla_plan',Lang::get('lang.SLA_plan')) !!} - {!! $errors->first('sla_plan', ':message') !!} + {!!Form::select('sla_plan', [''=>'Select a SLA Plan','SLA Plans'=>$slas->lists('name','id')],null,['class' => 'form-control']) !!} + {!! $errors->first('sla_plan', ':message') !!}
    @@ -127,7 +128,7 @@ class="active" {!! Form::label('auto_assign',Lang::get('lang.auto_assign')) !!} {!! $errors->first('auto_assign', ':message') !!} - {!!Form::select('auto_assign', [''=>'Select an Agent','Agents'=>$agents->lists('user_name','id')],null,['class' => 'form-control']) !!} + {!!Form::select('auto_assign', [''=>'Select an Agent','Agents'=>$agents->lists('first_name','id')],null,['class' => 'form-control']) !!} diff --git a/resources/views/themes/default1/admin/helpdesk/manage/helptopic/index.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/helptopic/index.blade.php index 48b28bd33..4c0a90688 100644 --- a/resources/views/themes/default1/admin/helpdesk/manage/helptopic/index.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/manage/helptopic/index.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Manage') -class="active" +active @stop @section('manage-bar') @@ -93,7 +93,7 @@ class="active" - @if($topic->ticket_status=='1') + @if($topic->status=='1') Active @else Disable diff --git a/resources/views/themes/default1/admin/helpdesk/manage/sla/create.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/sla/create.blade.php index f35529382..7e0a7dee9 100644 --- a/resources/views/themes/default1/admin/helpdesk/manage/sla/create.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/manage/sla/create.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Manage') -class="active" +active @stop @section('manage-bar') @@ -73,7 +73,7 @@ class="active" {!! Form::label('status',Lang::get('lang.status')) !!}  {!! $errors->first('status', ':message') !!} {!! Form::radio('status','1',true) !!} {{Lang::get('lang.active')}}   - {!! Form::radio('status','0') !!} {{Lang::get('lang.disabled')}} + {!! Form::radio('status','0') !!} {{Lang::get('lang.inactive')}} diff --git a/resources/views/themes/default1/admin/helpdesk/manage/sla/edit.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/sla/edit.blade.php index 5cc7cd13d..a6e7a3b1b 100644 --- a/resources/views/themes/default1/admin/helpdesk/manage/sla/edit.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/manage/sla/edit.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Manage') -class="active" +active @stop @section('manage-bar') @@ -71,9 +71,9 @@ class="active"
    {!! Form::label('status',Lang::get('lang.status')) !!}  - {!! $errors->first('status', ':message') !!} - {!! Form::radio('status','1',true) !!} {{Lang::get('lang.active')}}   - {!! Form::radio('status','0') !!} {{Lang::get('lang.disabled')}} + {!! $errors->first('status', ':message') !!}   + {!! Form::radio('status','1',true) !!}   {{Lang::get('lang.active')}}      + {!! Form::radio('status','0') !!}   {{Lang::get('lang.inactive')}}
    diff --git a/resources/views/themes/default1/admin/helpdesk/manage/sla/index.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/sla/index.blade.php index ae637d6ac..d4d93fd78 100644 --- a/resources/views/themes/default1/admin/helpdesk/manage/sla/index.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/manage/sla/index.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Manage') -class="active" +active @stop @section('manage-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/manage/workflow/create.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/workflow/create.blade.php new file mode 100644 index 000000000..ae5784d73 --- /dev/null +++ b/resources/views/themes/default1/admin/helpdesk/manage/workflow/create.blade.php @@ -0,0 +1,381 @@ +@extends('themes.default1.admin.layout.admin') + +@section('Manage') +active +@stop + +@section('manage-bar') +active +@stop + +@section('workflow') +class="active" +@stop + +@section('HeadInclude') +@stop + + +@section('PageHeader') +

    {!! Lang::get('lang.create_workflow') !!}

    +@stop + + +@section('breadcrumbs') + +@stop + + +@section('content') + +
    + +
    + + @if(Session::has('success')) +
    + + Success + + {!! Session::get('success') !!} +
    + @endif + + @if(Session::has('fails')) +
    + + Fail! + + {!! Session::get('fails') !!} +
    + @endif + @if(Session::has('errors')) +
    + + Alert! + +
    + @if($errors->first('name')) +
  • {!! $errors->first('name', ':message') !!}
  • + @endif + @if($errors->first('execution_order')) +
  • {!! $errors->first('execution_order', ':message') !!}
  • + @endif + @if($errors->first('target_channel')) +
  • {!! $errors->first('target_channel', ':message') !!}
  • + @endif + @if($errors->first('rule')) +
  • {!! $errors->first('rule', ':message') !!}
  • + @endif + @if($errors->first('action')) +
  • {!! $errors->first('action', ':message') !!}
  • + @endif +
    + @endif +
    + +
    + {!! Form::text('name',null,['class' => 'form-control', 'placeholder' => 'Name', 'id' => 'name']) !!} +
    +
    +
    + +
    +      +      +
    +
    +
    +
    + +
    + {!! Form::input('number', 'execution_order',null,['class' => 'form-control', 'placeholder' => 'Exceution Order', 'id' => 'execution_order', 'min' => '0']) !!} +
    +
    +
    +
    + +
    + {!! Form::select('target_channel', [''=> '-- Select a Channel --', 'A-0' => 'Any', 'A-1' => 'Web Forms', 'A-4' => 'API Calls', 'A-2' => 'Emails'], null,['class' => 'form-control', 'id' => 'execution_order']) !!} +
    +
    +
    +
    + +
    +
    + + +
    + +
    + + + + + +@stop diff --git a/resources/views/themes/default1/admin/helpdesk/manage/workflow/edit.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/workflow/edit.blade.php new file mode 100644 index 000000000..f73a89737 --- /dev/null +++ b/resources/views/themes/default1/admin/helpdesk/manage/workflow/edit.blade.php @@ -0,0 +1,520 @@ +@extends('themes.default1.admin.layout.admin') + +@section('Manage') +active +@stop + +@section('manage-bar') +active +@stop + +@section('workflow') +class="active" +@stop + +@section('HeadInclude') +@stop + + +@section('PageHeader') +

    {!! Lang::get('lang.edit_workflow') !!}

    +@stop + + +@section('breadcrumbs') + +@stop + + +@section('content') +
    +
    + +
    + + @if(Session::has('success')) +
    + + Success + + {{Session::get('success')}} +
    + @endif + + @if(Session::has('fails')) +
    + + Fail! + + {{Session::get('fails')}} +
    + @endif + @if(Session::has('errors')) +
    + + Alert! + +
    + @if($errors->first('name')) +
  • {!! $errors->first('name', ':message') !!}
  • + @endif + @if($errors->first('execution_order')) +
  • {!! $errors->first('execution_order', ':message') !!}
  • + @endif + @if($errors->first('target_channel')) +
  • {!! $errors->first('target_channel', ':message') !!}
  • + @endif + @if($errors->first('rule')) +
  • {!! $errors->first('rule', ':message') !!}
  • + @endif + @if($errors->first('action')) +
  • {!! $errors->first('action', ':message') !!}
  • + @endif +
    + @endif +
    + +
    + +
    +
    +
    + +
    + status == 1) { echo "checked"; } ?> >     + status == 0) { echo "checked"; } ?> >     +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + + +
    + + +
    +
    + +
    +
    + + +
    +
    + + +
    + +
    + +
    + + + +@stop diff --git a/resources/views/themes/default1/admin/helpdesk/manage/workflow/index.blade.php b/resources/views/themes/default1/admin/helpdesk/manage/workflow/index.blade.php new file mode 100644 index 000000000..f6dd65e74 --- /dev/null +++ b/resources/views/themes/default1/admin/helpdesk/manage/workflow/index.blade.php @@ -0,0 +1,90 @@ +@extends('themes.default1.admin.layout.admin') + +@section('Manage') +active +@stop + +@section('manage-bar') +active +@stop + +@section('workflow') +class="active" +@stop + +@section('HeadInclude') +@stop + +@section('PageHeader') +@stop + + +@section('breadcrumbs') + +@stop + + +@section('content') +
    +
    +
    +
    +

    {!! Lang::get('lang.ticket_workflow') !!}

    + {!! Lang::get('lang.create') !!} +
    + +
    + + @if(Session::has('success')) +
    + + Success + + {!! Session::get('success') !!} +
    + @endif + + @if(Session::has('fails')) +
    + + Fail! + + {!! Session::get('fails') !!} +
    + @endif + {!! Datatable::table() + ->addColumn(Lang::get('lang.name'), + Lang::get('lang.status'), + Lang::get('lang.order'), + Lang::get('lang.rules'), + Lang::get('lang.target_channel'), + Lang::get('lang.created'), + Lang::get('lang.updated'), + Lang::get('lang.action')) // these are the column headings to be shown + ->setUrl(route('workflow.list')) // this is the route where data will be retrieved + ->render() !!} +
    + + + + +
    + +
    + +
    + + +@stop diff --git a/resources/views/themes/default1/admin/helpdesk/setting.blade.php b/resources/views/themes/default1/admin/helpdesk/setting.blade.php index 3c0858989..051c579c3 100644 --- a/resources/views/themes/default1/admin/helpdesk/setting.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/setting.blade.php @@ -202,6 +202,19 @@ + +
    +
    + +
    {!! Lang::get('lang.workflow') !!}
    +
    +
    + @@ -314,6 +327,18 @@ +
    +
    + +
    {!! Lang::get('lang.cron') !!}
    +
    +
    + diff --git a/resources/views/themes/default1/admin/helpdesk/settings/alert.blade.php b/resources/views/themes/default1/admin/helpdesk/settings/alert.blade.php index fe8b4b73d..df588d970 100644 --- a/resources/views/themes/default1/admin/helpdesk/settings/alert.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/settings/alert.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Settings') -class="active" +active @stop @section('settings-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/settings/checkupdate.blade.php b/resources/views/themes/default1/admin/helpdesk/settings/checkupdate.blade.php index 7c64f1da2..c9b93fceb 100644 --- a/resources/views/themes/default1/admin/helpdesk/settings/checkupdate.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/settings/checkupdate.blade.php @@ -1,5 +1,7 @@ @extends('themes.default1.admin.layout.admin') - +@section('update') +class="active" +@stop @section('content')
    diff --git a/resources/views/themes/default1/admin/helpdesk/settings/company.blade.php b/resources/views/themes/default1/admin/helpdesk/settings/company.blade.php index e69e60b8f..4a15444fc 100644 --- a/resources/views/themes/default1/admin/helpdesk/settings/company.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/settings/company.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') - + @section('Settings') -class="active" +active @stop @section('settings-bar') @@ -70,8 +70,8 @@ class="active"
    {!! Form::label('company_name',Lang::get('lang.name')) !!} - {!! $errors->first('company_name', ':message') !!} {!! Form::text('company_name',$companys->company_name,['class' => 'form-control']) !!} + {!! $errors->first('company_name', ':message') !!}
    @@ -82,8 +82,9 @@ class="active"
    {!! Form::label('website',Lang::get('lang.website')) !!} - {!! $errors->first('website', ':message') !!} {!! Form::url('website',$companys->website,['class' => 'form-control']) !!} + {!! $errors->first('website', ':message') !!} +
    @@ -93,8 +94,8 @@ class="active"
    {!! Form::label('phone',Lang::get('lang.phone')) !!} - {!! $errors->first('phone', ':message') !!} {!! Form::text('phone',$companys->phone,['class' => 'form-control']) !!} + {!! $errors->first('phone', ':message') !!}
    @@ -149,6 +150,7 @@ class="active" +
    @if($companys->logo != null)
    {!! Form::checkbox('use_logo') !!} @@ -158,12 +160,69 @@ class="active" first(); ?> @if($companys->logo != null) -
    - User Image +
    +
    @endif +
    + + + + @stop \ No newline at end of file diff --git a/resources/views/themes/default1/admin/helpdesk/settings/crone.blade.php b/resources/views/themes/default1/admin/helpdesk/settings/crone.blade.php new file mode 100644 index 000000000..0f141848e --- /dev/null +++ b/resources/views/themes/default1/admin/helpdesk/settings/crone.blade.php @@ -0,0 +1,135 @@ +@extends('themes.default1.admin.layout.admin') + +@section('Settings') +active +@stop + +@section('settings-bar') +active +@stop + +@section('cron') +class="active" +@stop + +@section('HeadInclude') +@stop + +@section('PageHeader') +@stop + + +@section('breadcrumbs') + +@stop + + +@section('content') + + +{!! Form::model($emails,['url' => 'post-scheduler', 'method' => 'PATCH']) !!} +
    +
    +
    +
    +

    {{Lang::get('lang.cron')}}

    + {!! Form::submit(Lang::get('lang.save'),['class'=>'btn btn-primary'])!!} +
    +
    + + @if(Session::has('success')) +
    + + Success! + + {!!Session::get('success')!!} +
    + @endif + + @if(Session::has('fails')) +
    + + Fail! + + {!!Session::get('fails')!!} +
    + @endif +
    +
    +  {!!Lang::get('lang.crone-url-message')!!} + {!!Lang::get('lang.click')!!} {!!Lang::get('lang.check-cron-set')!!} + +
    +
    +
    + + +
    + +
    +
    + {!! Form::label('email_fetching',Lang::get('lang.email_fetch')) !!}
    + {!! Form::checkbox('email_fetching',1,true) !!} {{Lang::get('lang.fetch_auto-corn')}} +
    +
    +
    + + +
    + + + + +
    +
    +
    +
    +
    + + +
    + +
    +
    + {!! Form::label('email_fetching',Lang::get('lang.notification-email')) !!}
    + {!! Form::checkbox('notification_cron',1,true) !!} {{Lang::get('lang.cron_notification')}} +
    +
    +
    + + +
    + + + + +
    +
    + +
    +
    +
    +
    +
    + +@stop diff --git a/resources/views/themes/default1/admin/helpdesk/settings/email.blade.php b/resources/views/themes/default1/admin/helpdesk/settings/email.blade.php index d35b73870..f69632a5b 100644 --- a/resources/views/themes/default1/admin/helpdesk/settings/email.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/settings/email.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Settings') -class="active" +active @stop @section('settings-bar') @@ -68,20 +68,9 @@ class="active" - -
    -
    - {!! Form::label('email_fetching',Lang::get('lang.email_fetch')) !!}
    - {!! Form::checkbox('email_fetching',1,true) !!} {{Lang::get('lang.fetch_auto-corn')}} -
    -
    +
    -
    -
    - {!! Form::checkbox('notification_cron',1,true) !!} {{Lang::get('lang.cron_notification')}} -
    -
    diff --git a/resources/views/themes/default1/admin/helpdesk/settings/plugins.blade.php b/resources/views/themes/default1/admin/helpdesk/settings/plugins.blade.php index 4b65129f0..10da52862 100644 --- a/resources/views/themes/default1/admin/helpdesk/settings/plugins.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/settings/plugins.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') -@section('Settings') -class="active" +@section('Plugins') +active @stop @section('settings-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/settings/responder.blade.php b/resources/views/themes/default1/admin/helpdesk/settings/responder.blade.php index b1c23083a..a2b4de507 100644 --- a/resources/views/themes/default1/admin/helpdesk/settings/responder.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/settings/responder.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Settings') -class="active" +active @stop @section('settings-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/settings/system.blade.php b/resources/views/themes/default1/admin/helpdesk/settings/system.blade.php index dfe7fad38..a2f099e7c 100644 --- a/resources/views/themes/default1/admin/helpdesk/settings/system.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/settings/system.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Settings') -class="active" +active @stop @section('settings-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/settings/ticket.blade.php b/resources/views/themes/default1/admin/helpdesk/settings/ticket.blade.php index 45082b666..82ef9ba1a 100644 --- a/resources/views/themes/default1/admin/helpdesk/settings/ticket.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/settings/ticket.blade.php @@ -1,7 +1,7 @@ @extends('themes.default1.admin.layout.admin') @section('Settings') -class="active" +active @stop @section('settings-bar') diff --git a/resources/views/themes/default1/admin/helpdesk/theme/social.blade.php b/resources/views/themes/default1/admin/helpdesk/theme/social.blade.php index 0bd121f26..0f2f8397d 100644 --- a/resources/views/themes/default1/admin/helpdesk/theme/social.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/theme/social.blade.php @@ -1,14 +1,14 @@ @extends('themes.default1.admin.layout.admin') @section('Themes') -class="active" +active @stop @section('theme-bar') active @stop -@section('footer') +@section('socail') class="active" @stop diff --git a/resources/views/themes/default1/admin/helpdesk/theme/widgets.blade.php b/resources/views/themes/default1/admin/helpdesk/theme/widgets.blade.php index 1fd8e1b8c..6579751c0 100644 --- a/resources/views/themes/default1/admin/helpdesk/theme/widgets.blade.php +++ b/resources/views/themes/default1/admin/helpdesk/theme/widgets.blade.php @@ -1,14 +1,14 @@ @extends('themes.default1.admin.layout.admin') @section('Themes') -class="active" +active @stop @section('theme-bar') active @stop -@section('footer') +@section('widget') class="active" @stop diff --git a/resources/views/themes/default1/admin/layout/admin.blade.php b/resources/views/themes/default1/admin/layout/admin.blade.php index 1d1e60146..ed2e601ee 100644 --- a/resources/views/themes/default1/admin/layout/admin.blade.php +++ b/resources/views/themes/default1/admin/layout/admin.blade.php @@ -24,6 +24,7 @@ + @@ -53,23 +54,50 @@ + +
    @@ -141,53 +163,98 @@ + @@ -231,7 +299,7 @@ $i = count($tickets); first(); ?> - {!! Lang::get('lang.copyright') !!} © {!! date('Y') !!} {!! $company->company_name !!}. {!! Lang::get('lang.all_rights_reserved') !!}. {!! Lang::get('lang.powered_by') !!} Faveo + {!! Lang::get('lang.copyright') !!} © {!! date('Y') !!} {!! $company->company_name !!}. {!! Lang::get('lang.all_rights_reserved') !!}. {!! Lang::get('lang.powered_by') !!} Faveo diff --git a/resources/views/themes/default1/agent/helpdesk/dept-ticket/closed.blade.php b/resources/views/themes/default1/agent/helpdesk/dept-ticket/closed.blade.php index d109c2ea3..a15ff7fd0 100644 --- a/resources/views/themes/default1/agent/helpdesk/dept-ticket/closed.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/dept-ticket/closed.blade.php @@ -14,6 +14,7 @@ class="active" @section('content') first(); if(Auth::user()->role == 'agent') { @@ -56,8 +57,8 @@ $dept = App\Model\helpdesk\Agent\Department::where('name','=',$id)->first(); - - +
    @@ -68,12 +69,62 @@ $dept = App\Model\helpdesk\Agent\Department::where('name','=',$id)->first(); Lang::get('lang.ticket_id'), Lang::get('lang.priority'), Lang::get('lang.from'), - Lang::get('lang.last_replier'), Lang::get('lang.assigned_to'), Lang::get('lang.last_activity')) - ->setUrl(route('get.dept.close', $dept->id)) - ->setOrder(array(7=>'desc')) - ->setClass('table table-hover table-bordered table-striped') + ->setUrl(route('get.dept.close', $dept->id)) + ->setOptions('aoColumnDefs',array( + array( + 'render' => "function ( data, type, row ) { + var t = row[6].split(/[- :,/ :,. /]/); + var d = new Date(t[0], t[1]-1, t[2], t[3], t[4], t[5]); + + var dtf= '$date_time_format'; + if(dtf==1) { + dtf = 'D/MMM/YYYY hh:mm:ss A'; + } else if(dtf==2) { + dtf = 'D MMM, YYYY hh:mm:ss A'; + } else if(dtf==3) { + dtf = 'D-MMM-YYYY hh:mm:ss A'; + } else if(dtf==4) { + dtf = 'MMM/D/YYYY hh:mm:ss A'; + } else if(dtf==5) { + dtf = 'MMM D, YYYY hh:mm:ss A'; + } else if(dtf==6) { + dtf = 'MMM-D-YYYY hh:mm:ss A'; + } else if(dtf==7) { + dtf = 'YYYY/MMM/D hh:mm:ss A'; + } else if(dtf==8) { + dtf = 'YYYY, MMM D hh:mm:ss A'; + } else if(dtf==9) { + dtf = 'YYYY-MMM-D hh:mm:ss A'; + } + return moment(d).format(dtf); + + }", + 'aTargets' => array(6)) + )) + ->setOrder(array(6=>'desc')) + ->setClass('table table-hover table-bordered table-striped') + ->setCallbacks("fnRowCallback",'function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + var str = aData[3]; + if(str.search("#000") == -1) { + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px #F3F3F3"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "font-weight":"600", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd","border-right":"solid 0.5px #F3F3F3"}); + }); + } else { + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + }); + } + }') ->render();!!}
    diff --git a/resources/views/themes/default1/agent/helpdesk/dept-ticket/inprogress.blade.php b/resources/views/themes/default1/agent/helpdesk/dept-ticket/inprogress.blade.php index a581e073e..fe5846240 100644 --- a/resources/views/themes/default1/agent/helpdesk/dept-ticket/inprogress.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/dept-ticket/inprogress.blade.php @@ -15,6 +15,7 @@ class="active" @section('content') first(); if (Auth::user()->role == 'agent') { @@ -69,12 +70,62 @@ if (Auth::user()->role == 'agent') { Lang::get('lang.ticket_id'), Lang::get('lang.priority'), Lang::get('lang.from'), - Lang::get('lang.last_replier'), Lang::get('lang.assigned_to'), Lang::get('lang.last_activity')) - ->setUrl(route('get.dept.inprocess', $dept->id)) - ->setOrder(array(7=>'desc')) - ->setClass('table table-hover table-bordered table-striped') + ->setUrl(route('get.dept.inprocess', $dept->id)) + ->setOptions('aoColumnDefs',array( + array( + 'render' => "function ( data, type, row ) { + var t = row[6].split(/[- :,/ :,. /]/); + var d = new Date(t[0], t[1]-1, t[2], t[3], t[4], t[5]); + + var dtf= '$date_time_format'; + if(dtf==1) { + dtf = 'D/MMM/YYYY hh:mm:ss A'; + } else if(dtf==2) { + dtf = 'D MMM, YYYY hh:mm:ss A'; + } else if(dtf==3) { + dtf = 'D-MMM-YYYY hh:mm:ss A'; + } else if(dtf==4) { + dtf = 'MMM/D/YYYY hh:mm:ss A'; + } else if(dtf==5) { + dtf = 'MMM D, YYYY hh:mm:ss A'; + } else if(dtf==6) { + dtf = 'MMM-D-YYYY hh:mm:ss A'; + } else if(dtf==7) { + dtf = 'YYYY/MMM/D hh:mm:ss A'; + } else if(dtf==8) { + dtf = 'YYYY, MMM D hh:mm:ss A'; + } else if(dtf==9) { + dtf = 'YYYY-MMM-D hh:mm:ss A'; + } + return moment(d).format(dtf); + + }", + 'aTargets' => array(6)) + )) + ->setOrder(array(6=>'desc')) + ->setClass('table table-hover table-bordered table-striped') + ->setCallbacks("fnRowCallback",'function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + var str = aData[3]; + if(str.search("#000") == -1) { + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px #F3F3F3"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "font-weight":"600", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd","border-right":"solid 0.5px #F3F3F3"}); + }); + } else { + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + }); + } + }') ->render();!!} diff --git a/resources/views/themes/default1/agent/helpdesk/dept-ticket/open.blade.php b/resources/views/themes/default1/agent/helpdesk/dept-ticket/open.blade.php index e996a4f7c..22f01fcbf 100644 --- a/resources/views/themes/default1/agent/helpdesk/dept-ticket/open.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/dept-ticket/open.blade.php @@ -13,7 +13,8 @@ class="active" @stop @section('content') -first(); if(Auth::user()->role == 'agent') { $tickets = App\Model\helpdesk\Ticket\Tickets::where('status','=','1')->where('isanswered','=', 0)->where('dept_id','=',$dept->id)->orderBy('id', 'DESC')->paginate(20); @@ -67,12 +68,62 @@ $dept = App\Model\helpdesk\Agent\Department::where('name','=',$id)->first(); Lang::get('lang.ticket_id'), Lang::get('lang.priority'), Lang::get('lang.from'), - Lang::get('lang.last_replier'), Lang::get('lang.assigned_to'), Lang::get('lang.last_activity')) - ->setUrl(route('get.dept.open', $dept->id)) - ->setOrder(array(7=>'desc')) - ->setClass('table table-hover table-bordered table-striped') + ->setUrl(route('get.dept.open', $dept->id)) + ->setOptions('aoColumnDefs',array( + array( + 'render' => "function ( data, type, row ) { + var t = row[6].split(/[- :,/ :,. /]/); + var d = new Date(t[0], t[1]-1, t[2], t[3], t[4], t[5]); + + var dtf= '$date_time_format'; + if(dtf==1) { + dtf = 'D/MMM/YYYY hh:mm:ss A'; + } else if(dtf==2) { + dtf = 'D MMM, YYYY hh:mm:ss A'; + } else if(dtf==3) { + dtf = 'D-MMM-YYYY hh:mm:ss A'; + } else if(dtf==4) { + dtf = 'MMM/D/YYYY hh:mm:ss A'; + } else if(dtf==5) { + dtf = 'MMM D, YYYY hh:mm:ss A'; + } else if(dtf==6) { + dtf = 'MMM-D-YYYY hh:mm:ss A'; + } else if(dtf==7) { + dtf = 'YYYY/MMM/D hh:mm:ss A'; + } else if(dtf==8) { + dtf = 'YYYY, MMM D hh:mm:ss A'; + } else if(dtf==9) { + dtf = 'YYYY-MMM-D hh:mm:ss A'; + } + return moment(d).format(dtf); + + }", + 'aTargets' => array(6)) + )) + ->setOrder(array(6=>'desc')) + ->setClass('table table-hover table-bordered table-striped') + ->setCallbacks("fnRowCallback",'function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + var str = aData[3]; + if(str.search("#000") == -1) { + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px #F3F3F3"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "font-weight":"600", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd","border-right":"solid 0.5px #F3F3F3"}); + }); + } else { + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + }); + } + }') ->render();!!} diff --git a/resources/views/themes/default1/agent/helpdesk/organization/create.blade.php b/resources/views/themes/default1/agent/helpdesk/organization/create.blade.php index 957c3cf19..da804fa3f 100644 --- a/resources/views/themes/default1/agent/helpdesk/organization/create.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/organization/create.blade.php @@ -43,20 +43,20 @@ class="active"
    {!! Form::label('name',Lang::get('lang.name')) !!} - {!! $errors->first('name', ':message') !!} {!! Form::text('name',null,['class' => 'form-control']) !!} + {!! $errors->first('name', ':message') !!}
    {!! Form::label('phone',Lang::get('lang.phone')) !!} - {!! $errors->first('phone', ':message') !!} {!! Form::text('phone',null,['class' => 'form-control']) !!} + {!! $errors->first('phone', ':message') !!}
    {!! Form::label('website',Lang::get('lang.website')) !!} - {!! $errors->first('website', ':message') !!} {!! Form::text('website',null,['class' => 'form-control']) !!} + {!! $errors->first('website', ':message') !!}
    diff --git a/resources/views/themes/default1/agent/helpdesk/organization/edit.blade.php b/resources/views/themes/default1/agent/helpdesk/organization/edit.blade.php index 5ca573969..d4182852c 100644 --- a/resources/views/themes/default1/agent/helpdesk/organization/edit.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/organization/edit.blade.php @@ -42,20 +42,20 @@ class="active"
    {!! Form::label('name',Lang::get('lang.name')) !!} - {!! $errors->first('name', ':message') !!} {!! Form::text('name',null,['class' => 'form-control']) !!} + {!! $errors->first('name', ':message') !!}
    {!! Form::label('phone',Lang::get('lang.phone')) !!} - {!! $errors->first('phone', ':message') !!} {!! Form::text('phone',null,['class' => 'form-control']) !!} + {!! $errors->first('phone', ':message') !!}
    {!! Form::label('website',Lang::get('lang.website')) !!} - {!! $errors->first('website', ':message') !!} {!! Form::text('website',null,['class' => 'form-control']) !!} + {!! $errors->first('website', ':message') !!}
    diff --git a/resources/views/themes/default1/agent/helpdesk/ticket/answered.blade.php b/resources/views/themes/default1/agent/helpdesk/ticket/answered.blade.php index 3bf63a2a1..5e0153bd2 100644 --- a/resources/views/themes/default1/agent/helpdesk/ticket/answered.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/ticket/answered.blade.php @@ -13,7 +13,8 @@ class="active" @stop @section('content') -role == 'agent') { $dept = App\Model\helpdesk\Agent\Department::where('id','=',Auth::user()->primary_dpt)->first(); @@ -70,12 +71,62 @@ class="active" Lang::get('lang.ticket_id'), Lang::get('lang.priority'), Lang::get('lang.from'), - Lang::get('lang.last_replier'), Lang::get('lang.assigned_to'), Lang::get('lang.last_activity')) - ->setUrl(route('get.answered.ticket')) - ->setOrder(array(7=>'desc')) - ->setClass('table table-hover table-bordered table-striped') + ->setUrl(route('get.answered.ticket')) + ->setOptions('aoColumnDefs',array( + array( + 'render' => "function ( data, type, row ) { + var t = row[6].split(/[- :,/ :,. /]/); + var d = new Date(t[0], t[1]-1, t[2], t[3], t[4], t[5]); + + var dtf= '$date_time_format'; + if(dtf==1) { + dtf = 'D/MMM/YYYY hh:mm:ss A'; + } else if(dtf==2) { + dtf = 'D MMM, YYYY hh:mm:ss A'; + } else if(dtf==3) { + dtf = 'D-MMM-YYYY hh:mm:ss A'; + } else if(dtf==4) { + dtf = 'MMM/D/YYYY hh:mm:ss A'; + } else if(dtf==5) { + dtf = 'MMM D, YYYY hh:mm:ss A'; + } else if(dtf==6) { + dtf = 'MMM-D-YYYY hh:mm:ss A'; + } else if(dtf==7) { + dtf = 'YYYY/MMM/D hh:mm:ss A'; + } else if(dtf==8) { + dtf = 'YYYY, MMM D hh:mm:ss A'; + } else if(dtf==9) { + dtf = 'YYYY-MMM-D hh:mm:ss A'; + } + return moment(d).format(dtf); + + }", + 'aTargets' => array(6)) + )) + ->setOrder(array(6=>'desc')) + ->setClass('table table-hover table-bordered table-striped') + ->setCallbacks("fnRowCallback",'function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + var str = aData[3]; + if(str.search("#000") == -1) { + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px #F3F3F3"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "font-weight":"600", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd","border-right":"solid 0.5px #F3F3F3"}); + }); + } else { + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + }); + } + }') ->render();!!} diff --git a/resources/views/themes/default1/agent/helpdesk/ticket/assigned.blade.php b/resources/views/themes/default1/agent/helpdesk/ticket/assigned.blade.php index 1d6f9516b..9a76ba74f 100644 --- a/resources/views/themes/default1/agent/helpdesk/ticket/assigned.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/ticket/assigned.blade.php @@ -13,7 +13,8 @@ class="active" @stop @section('content') -role == 'agent') { $dept = App\Model\helpdesk\Agent\Department::where('id','=',Auth::user()->primary_dpt)->first(); $tickets = App\Model\helpdesk\Ticket\Tickets::where('status', '=', 1)->where('assigned_to', '>', 0)->where('dept_id','=',$dept->id)->orderBy('id', 'DESC')->paginate(20); @@ -62,12 +63,62 @@ class="active" Lang::get('lang.ticket_id'), Lang::get('lang.priority'), Lang::get('lang.from'), - Lang::get('lang.last_replier'), Lang::get('lang.assigned_to'), Lang::get('lang.last_activity')) - ->setUrl(route('get.assigned.ticket')) - ->setOrder(array(7=>'desc')) - ->setClass('table table-hover table-bordered table-striped') + ->setUrl(route('get.assigned.ticket')) + ->setOptions('aoColumnDefs',array( + array( + 'render' => "function ( data, type, row ) { + var t = row[6].split(/[- :,/ :,. /]/); + var d = new Date(t[0], t[1]-1, t[2], t[3], t[4], t[5]); + + var dtf= '$date_time_format'; + if(dtf==1) { + dtf = 'D/MMM/YYYY hh:mm:ss A'; + } else if(dtf==2) { + dtf = 'D MMM, YYYY hh:mm:ss A'; + } else if(dtf==3) { + dtf = 'D-MMM-YYYY hh:mm:ss A'; + } else if(dtf==4) { + dtf = 'MMM/D/YYYY hh:mm:ss A'; + } else if(dtf==5) { + dtf = 'MMM D, YYYY hh:mm:ss A'; + } else if(dtf==6) { + dtf = 'MMM-D-YYYY hh:mm:ss A'; + } else if(dtf==7) { + dtf = 'YYYY/MMM/D hh:mm:ss A'; + } else if(dtf==8) { + dtf = 'YYYY, MMM D hh:mm:ss A'; + } else if(dtf==9) { + dtf = 'YYYY-MMM-D hh:mm:ss A'; + } + return moment(d).format(dtf); + + }", + 'aTargets' => array(6)) + )) + ->setOrder(array(6=>'desc')) + ->setClass('table table-hover table-bordered table-striped') + ->setCallbacks("fnRowCallback",'function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + var str = aData[3]; + if(str.search("#000") == -1) { + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px #F3F3F3"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "font-weight":"600", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd","border-right":"solid 0.5px #F3F3F3"}); + }); + } else { + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + }); + } + }') ->render();!!} {!! Form::close() !!} diff --git a/resources/views/themes/default1/agent/helpdesk/ticket/closed.blade.php b/resources/views/themes/default1/agent/helpdesk/ticket/closed.blade.php index 11cd867f4..647671202 100644 --- a/resources/views/themes/default1/agent/helpdesk/ticket/closed.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/ticket/closed.blade.php @@ -14,6 +14,7 @@ class="active" @section('content') role == 'agent') { $dept = App\Model\helpdesk\Agent\Department::where('id','=',Auth::user()->primary_dpt)->first(); $tickets = App\Model\helpdesk\Ticket\Tickets::where('status', '>', 1)->where('dept_id','=',$dept->id)->where('status', '<', 4)->orderBy('id', 'DESC')->paginate(20); @@ -62,12 +63,62 @@ class="active" Lang::get('lang.ticket_id'), Lang::get('lang.priority'), Lang::get('lang.from'), - Lang::get('lang.last_replier'), Lang::get('lang.assigned_to'), Lang::get('lang.last_activity')) - ->setUrl(route('get.closed.ticket')) - ->setOrder(array(7=>'desc')) - ->setClass('table table-hover table-bordered table-striped') + ->setUrl(route('get.closed.ticket')) + ->setOptions('aoColumnDefs',array( + array( + 'render' => "function ( data, type, row ) { + var t = row[6].split(/[- :,/ :,. /]/); + var d = new Date(t[0], t[1]-1, t[2], t[3], t[4], t[5]); + + var dtf= '$date_time_format'; + if(dtf==1) { + dtf = 'D/MMM/YYYY hh:mm:ss A'; + } else if(dtf==2) { + dtf = 'D MMM, YYYY hh:mm:ss A'; + } else if(dtf==3) { + dtf = 'D-MMM-YYYY hh:mm:ss A'; + } else if(dtf==4) { + dtf = 'MMM/D/YYYY hh:mm:ss A'; + } else if(dtf==5) { + dtf = 'MMM D, YYYY hh:mm:ss A'; + } else if(dtf==6) { + dtf = 'MMM-D-YYYY hh:mm:ss A'; + } else if(dtf==7) { + dtf = 'YYYY/MMM/D hh:mm:ss A'; + } else if(dtf==8) { + dtf = 'YYYY, MMM D hh:mm:ss A'; + } else if(dtf==9) { + dtf = 'YYYY-MMM-D hh:mm:ss A'; + } + return moment(d).format(dtf); + + }", + 'aTargets' => array(6)) + )) + ->setOrder(array(6=>'desc')) + ->setClass('table table-hover table-bordered table-striped') + ->setCallbacks("fnRowCallback",'function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + var str = aData[3]; + if(str.search("#000") == -1) { + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px #F3F3F3"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "font-weight":"600", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd","border-right":"solid 0.5px #F3F3F3"}); + }); + } else { + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + }); + } + }') ->render();!!} diff --git a/resources/views/themes/default1/agent/helpdesk/ticket/inbox.blade.php b/resources/views/themes/default1/agent/helpdesk/ticket/inbox.blade.php index 6b47ceb4f..9c22363a0 100644 --- a/resources/views/themes/default1/agent/helpdesk/ticket/inbox.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/ticket/inbox.blade.php @@ -13,7 +13,8 @@ class="active" @stop @section('content') -role == 'agent') { $dept = App\Model\helpdesk\Agent\Department::where('id','=',Auth::user()->primary_dpt)->first(); $tickets = App\Model\helpdesk\Ticket\Tickets::where('status', '=', 1)->where('dept_id','=',$dept->id)->orderBy('id', 'DESC')->paginate(20); @@ -61,12 +62,62 @@ class="active" Lang::get('lang.ticket_id'), Lang::get('lang.priority'), Lang::get('lang.from'), - Lang::get('lang.last_replier'), Lang::get('lang.assigned_to'), Lang::get('lang.last_activity')) - ->setUrl(route('get.inbox.ticket')) - ->setOrder(array(7=>'desc')) - ->setClass('table table-hover table-bordered table-striped') + ->setUrl(route('get.inbox.ticket')) + ->setOptions('aoColumnDefs',array( + array( + 'render' => "function ( data, type, row ) { + var t = row[6].split(/[- :,/ :,. /]/); + var d = new Date(t[0], t[1]-1, t[2], t[3], t[4], t[5]); + + var dtf= '$date_time_format'; + if(dtf==1) { + dtf = 'D/MMM/YYYY hh:mm:ss A'; + } else if(dtf==2) { + dtf = 'D MMM, YYYY hh:mm:ss A'; + } else if(dtf==3) { + dtf = 'D-MMM-YYYY hh:mm:ss A'; + } else if(dtf==4) { + dtf = 'MMM/D/YYYY hh:mm:ss A'; + } else if(dtf==5) { + dtf = 'MMM D, YYYY hh:mm:ss A'; + } else if(dtf==6) { + dtf = 'MMM-D-YYYY hh:mm:ss A'; + } else if(dtf==7) { + dtf = 'YYYY/MMM/D hh:mm:ss A'; + } else if(dtf==8) { + dtf = 'YYYY, MMM D hh:mm:ss A'; + } else if(dtf==9) { + dtf = 'YYYY-MMM-D hh:mm:ss A'; + } + return moment(d).format(dtf); + + }", + 'aTargets' => array(6)) + )) + ->setOrder(array(6=>'desc')) + ->setClass('table table-hover table-bordered table-striped') + ->setCallbacks("fnCreatedRow", 'function( nRow, aData, iDataIndex ) { + var str = aData[3]; + if(str.search("#000") == -1) { + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px #F3F3F3"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "font-weight":"600", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd","border-right":"solid 0.5px #F3F3F3"}); + }); + } else { + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + }); + } + }') ->render();!!} diff --git a/resources/views/themes/default1/agent/helpdesk/ticket/myticket.blade.php b/resources/views/themes/default1/agent/helpdesk/ticket/myticket.blade.php index 571ae0527..0d923fb31 100644 --- a/resources/views/themes/default1/agent/helpdesk/ticket/myticket.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/ticket/myticket.blade.php @@ -13,7 +13,8 @@ class="active" @stop @section('content') -role == 'agent') { $dept = App\Model\helpdesk\Agent\Department::where('id','=',Auth::user()->primary_dpt)->first(); $tickets = App\Model\helpdesk\Ticket\Tickets::where('status', '=', 1)->where('assigned_to', '=', Auth::user()->id)->orderBy('id', 'ASC')->paginate(20); @@ -62,12 +63,62 @@ class="active" Lang::get('lang.ticket_id'), Lang::get('lang.priority'), Lang::get('lang.from'), - Lang::get('lang.last_replier'), Lang::get('lang.assigned_to'), Lang::get('lang.last_activity')) - ->setUrl(route('get.myticket.ticket')) - ->setOrder(array(7=>'desc')) - ->setClass('table table-hover table-bordered table-striped') + ->setUrl(route('get.myticket.ticket')) + ->setOptions('aoColumnDefs',array( + array( + 'render' => "function ( data, type, row ) { + var t = row[6].split(/[- :,/ :,. /]/); + var d = new Date(t[0], t[1]-1, t[2], t[3], t[4], t[5]); + + var dtf= '$date_time_format'; + if(dtf==1) { + dtf = 'D/MMM/YYYY hh:mm:ss A'; + } else if(dtf==2) { + dtf = 'D MMM, YYYY hh:mm:ss A'; + } else if(dtf==3) { + dtf = 'D-MMM-YYYY hh:mm:ss A'; + } else if(dtf==4) { + dtf = 'MMM/D/YYYY hh:mm:ss A'; + } else if(dtf==5) { + dtf = 'MMM D, YYYY hh:mm:ss A'; + } else if(dtf==6) { + dtf = 'MMM-D-YYYY hh:mm:ss A'; + } else if(dtf==7) { + dtf = 'YYYY/MMM/D hh:mm:ss A'; + } else if(dtf==8) { + dtf = 'YYYY, MMM D hh:mm:ss A'; + } else if(dtf==9) { + dtf = 'YYYY-MMM-D hh:mm:ss A'; + } + return moment(d).format(dtf); + + }", + 'aTargets' => array(6)) + )) + ->setOrder(array(6=>'desc')) + ->setClass('table table-hover table-bordered table-striped') + ->setCallbacks("fnRowCallback",'function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + var str = aData[3]; + if(str.search("#000") == -1) { + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px #F3F3F3"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "font-weight":"600", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd","border-right":"solid 0.5px #F3F3F3"}); + }); + } else { + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + }); + } + }') ->render();!!} diff --git a/resources/views/themes/default1/agent/helpdesk/ticket/open.blade.php b/resources/views/themes/default1/agent/helpdesk/ticket/open.blade.php index 75ee082b1..fe8207a59 100644 --- a/resources/views/themes/default1/agent/helpdesk/ticket/open.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/ticket/open.blade.php @@ -14,6 +14,7 @@ class="active" @section('content') role == 'agent') { $dept = App\Model\helpdesk\Agent\Department::where('id','=',Auth::user()->primary_dpt)->first(); $tickets = App\Model\helpdesk\Ticket\Tickets::where('status', '=', 1)->where('isanswered', '=', 0)->where('dept_id','=',$dept->id)->orderBy('id', 'DESC')->paginate(20); @@ -67,12 +68,62 @@ class="active" Lang::get('lang.ticket_id'), Lang::get('lang.priority'), Lang::get('lang.from'), - Lang::get('lang.last_replier'), Lang::get('lang.assigned_to'), Lang::get('lang.last_activity')) - ->setUrl(route('get.open.ticket')) - ->setOrder(array(7=>'desc')) - ->setClass('table table-hover table-bordered table-striped') + ->setUrl(route('get.open.ticket')) + ->setOptions('aoColumnDefs',array( + array( + 'render' => "function ( data, type, row ) { + var t = row[6].split(/[- :,/ :,. /]/); + var d = new Date(t[0], t[1]-1, t[2], t[3], t[4], t[5]); + + var dtf= '$date_time_format'; + if(dtf==1) { + dtf = 'D/MMM/YYYY hh:mm:ss A'; + } else if(dtf==2) { + dtf = 'D MMM, YYYY hh:mm:ss A'; + } else if(dtf==3) { + dtf = 'D-MMM-YYYY hh:mm:ss A'; + } else if(dtf==4) { + dtf = 'MMM/D/YYYY hh:mm:ss A'; + } else if(dtf==5) { + dtf = 'MMM D, YYYY hh:mm:ss A'; + } else if(dtf==6) { + dtf = 'MMM-D-YYYY hh:mm:ss A'; + } else if(dtf==7) { + dtf = 'YYYY/MMM/D hh:mm:ss A'; + } else if(dtf==8) { + dtf = 'YYYY, MMM D hh:mm:ss A'; + } else if(dtf==9) { + dtf = 'YYYY-MMM-D hh:mm:ss A'; + } + return moment(d).format(dtf); + + }", + 'aTargets' => array(6)) + )) + ->setOrder(array(6=>'desc')) + ->setClass('table table-hover table-bordered table-striped') + ->setCallbacks("fnRowCallback",'function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + var str = aData[3]; + if(str.search("#000") == -1) { + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px #F3F3F3"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "font-weight":"600", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd","border-right":"solid 0.5px #F3F3F3"}); + }); + } else { + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + }); + } + }') ->render();!!} diff --git a/resources/views/themes/default1/agent/helpdesk/ticket/overdue.blade.php b/resources/views/themes/default1/agent/helpdesk/ticket/overdue.blade.php index 7929f32f9..037f2e0d4 100644 --- a/resources/views/themes/default1/agent/helpdesk/ticket/overdue.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/ticket/overdue.blade.php @@ -14,22 +14,44 @@ class="active" @section('content') role == 'agent') { - $dept = App\Model\helpdesk\Agent\Department::where('id','=',Auth::user()->primary_dpt)->first(); - $tickets = App\Model\helpdesk\Ticket\Tickets::where('status', '=', 1)->where('dept_id','=',$dept->id)->orderBy('id', 'DESC')->paginate(20); - } else { - $tickets = App\Model\helpdesk\Ticket\Tickets::where('status', '=', 1)->orderBy('id', 'DESC')->paginate(20); - } + $date_time_format = UTC::getDateTimeFormat(); +if (Auth::user()->role == 'agent') { + $dept = Department::where('id', '=', Auth::user()->primary_dpt)->first(); + $overdues = App\Model\helpdesk\Ticket\Tickets::where('status', '=', 1)->where('isanswered', '=', 0)->where('dept_id', '=', $dept->id)->orderBy('id', 'DESC')->get(); + } else { + $overdues = App\Model\helpdesk\Ticket\Tickets::where('status', '=', 1)->where('isanswered', '=', 0)->orderBy('id', 'DESC')->get(); + } +$i = count($overdues); +if ($i == 0) { + $overdue_ticket = 0; + } else { + $j = 0; + foreach ($overdues as $overdue) { + $sla_plan = App\Model\helpdesk\Manage\Sla_plan::where('id', '=', $overdue->sla)->first(); + + $ovadate = $overdue->created_at; + $new_date = date_add($ovadate, date_interval_create_from_date_string($sla_plan->grace_period)).'

    '; + if (date('Y-m-d H:i:s') > $new_date) { + $j++; + //$value[] = $overdue; + } + } + // dd(count($value)); + if ($j > 0) { + $overdue_ticket = $j; + } else { + $overdue_ticket = 0; + } + } ?>
    -
    -

    Overdue

    {!! $tickets->total() !!} tickets +
    +

    {!! Lang::get('lang.overdue') !!}

    {!! $overdue_ticket !!} {!! Lang::get('lang.tickets') !!}
    @if(Session::has('success'))
    - - Success + Success {{Session::get('success')}}
    @@ -37,165 +59,437 @@ class="active" @if(Session::has('fails'))
    - - Fail! + Fail! {{Session::get('fails')}}
    @endif -
    - - {!! Form::open(['route'=>'select_all','method'=>'post']) !!} - +
    + {!! Form::open(['id'=>'modalpopup', 'route'=>'select_all','method'=>'post']) !!}
    -

    {!! $tickets->count().'-'.$tickets->total(); !!}

    - - - + {{-- --}} + + + +
    -
    - - - - - - - - - - - - - - - - @foreach ($tickets as $ticket ) - seen_by == null) {?> style="color:green;" sla; - $SlaPlan = App\Model\helpdesk\Manage\Sla_plan::where('id', '=', $sla)->first(); - - $time = $ticket->created_at; - $time = date_create($time); - date_add($time, date_interval_create_from_date_string($SlaPlan->grace_period)); - echo date_format($time, 'd/m/Y H:i:s'); - -?> > - - id)->get(); - $collab = count($collaborators); - // title - $title = App\Model\helpdesk\Ticket\Ticket_Thread::where('ticket_id', '=', $ticket->id)->first(); - $string = strip_tags($title->title); - // check atatchments - $attachments = App\Model\helpdesk\Ticket\Ticket_attachments::where('thread_id','=',$title->id)->first(); - $attach = count($attachments); - - if (strlen($string) > 40) { - $stringCut = substr($string, 0, 40); - $string = substr($stringCut, 0, strrpos($stringCut, ' ')).' ...'; - } - $TicketData = App\Model\helpdesk\Ticket\Ticket_Thread::where('ticket_id', '=', $ticket->id)->max('id'); - $TicketDatarow = App\Model\helpdesk\Ticket\Ticket_Thread::where('id', '=', $TicketData)->first(); - $LastResponse = App\User::where('id', '=', $TicketDatarow->user_id)->first(); - if($LastResponse->role == "user") { - $rep = "#F39C12"; - $username = $LastResponse->user_name; - } else { $rep = "#000"; $username = $LastResponse->first_name ." ". $LastResponse->last_name; - if($LastResponse->first_name==null || $LastResponse->last_name==null) { - $username = $LastResponse->user_name; - }} - $titles = App\Model\helpdesk\Ticket\Ticket_Thread::where('ticket_id', '=', $ticket->id)->get(); - $count = count($titles); - foreach($titles as $title) - { - $title = $title; - } - $assigned_to = App\User::where('id','=',$ticket->assigned_to)->first(); - if($assigned_to == null) - { - $assigned = "Unassigned"; - } - else - { - $assigned = $assigned_to->first_name ." ". $assigned_to->last_name; - } - ?> - - - priority_id)->first();?> - - user_id)->first(); ?> - @if($from->role == "user") - - @else - - @endif - - - - - @endforeach - -
    SubjectTicket IDPriorityFromLast ReplierAssigned ToLast Activity
    {{$string}} ({!! $count!!}) - @if($collab > 0) @endif - @if($attach > 0) @endif#{!! $ticket->ticket_number !!}{{$priority->priority_desc}}{!! $from->user_name !!}{!! $from->first_name." ".$from->last_name !!}{!! $username !!}{!! $assigned !!}{!! UTC::usertimezone($title->updated_at) !!}
    -
    - setPath(url('/ticket/overdue'))->render();?>  -
    +
    + + {!! Datatable::table() + ->addColumn( + "", + Lang::get('lang.subject'), + Lang::get('lang.ticket_id'), + Lang::get('lang.priority'), + Lang::get('lang.from'), + Lang::get('lang.assigned_to'), + Lang::get('lang.last_activity')) + ->setUrl(route('get.overdue.ticket')) + ->setOptions('aoColumnDefs',array( + array( + 'render' => "function ( data, type, row ) { + var t = row[6].split(/[- :,/ :,. /]/); + var d = new Date(t[0], t[1]-1, t[2], t[3], t[4], t[5]); + + var dtf= '$date_time_format'; + if(dtf==1) { + dtf = 'D/MMM/YYYY hh:mm:ss A'; + } else if(dtf==2) { + dtf = 'D MMM, YYYY hh:mm:ss A'; + } else if(dtf==3) { + dtf = 'D-MMM-YYYY hh:mm:ss A'; + } else if(dtf==4) { + dtf = 'MMM/D/YYYY hh:mm:ss A'; + } else if(dtf==5) { + dtf = 'MMM D, YYYY hh:mm:ss A'; + } else if(dtf==6) { + dtf = 'MMM-D-YYYY hh:mm:ss A'; + } else if(dtf==7) { + dtf = 'YYYY/MMM/D hh:mm:ss A'; + } else if(dtf==8) { + dtf = 'YYYY, MMM D hh:mm:ss A'; + } else if(dtf==9) { + dtf = 'YYYY-MMM-D hh:mm:ss A'; + } + return moment(d).format(dtf); + + }", + 'aTargets' => array(6)) + )) + ->setOrder(array(6=>'desc')) + ->setClass('table table-hover table-bordered table-striped') + ->setCallbacks("fnRowCallback",'function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + var str = aData[3]; + if(str.search("#000") == -1) { + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px #F3F3F3"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "font-weight":"600", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"#F3F3F3", "font-weight":"600", "border-bottom":"solid 0.5px #ddd","border-right":"solid 0.5px #F3F3F3"}); + }); + } else { + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + $("td", nRow).mouseenter(function(){ + $("td", nRow).css({"background-color":"#DEDFE0", "border":"none"}); + }); + $("td", nRow).mouseleave(function(){ + $("td", nRow).css({"background-color":"white", "border-bottom":"solid 0.5px #ddd", "border-right":"solid 0.5px white"}); + }); + } + }') + ->render();!!} +
    {!! Form::close() !!}
    + + + + + + @stop \ No newline at end of file diff --git a/resources/views/themes/default1/agent/helpdesk/ticket/timeline.blade.php b/resources/views/themes/default1/agent/helpdesk/ticket/timeline.blade.php index dc5205057..be3f939e7 100644 --- a/resources/views/themes/default1/agent/helpdesk/ticket/timeline.blade.php +++ b/resources/views/themes/default1/agent/helpdesk/ticket/timeline.blade.php @@ -61,11 +61,12 @@ active
  • Reply Rating: - ratingreply=='1')?'checked':'' ?> /> - ratingreply=='2')?'checked':'' ?> /> - ratingreply=='3')?'checked':'' ?> /> - ratingreply=='4')?'checked':'' ?> /> - ratingreply=='5')?'checked':'' ?> /> + + /> + /> + /> + /> + />
  • @@ -107,13 +108,15 @@ active
    can_delete_ticket == 1 || $group->can_ban_email == 1) {?> -
    +
    -