<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>jq.Schedule Demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">


    <style>


.jq-schedule *{box-sizing:border-box}
.jq-schedule .sc_wrapper::after,.jq-schedule .sc_menu::after{content:"";display:table;clear:both}
.jq-schedule .sc_menu{width:100%;height:26px}
.jq-schedule .sc_menu .sc_header_cell{float:left}
.jq-schedule .sc_menu .sc_header{float:left;height:26px;position:relative;overflow:hidden}
.jq-schedule .sc_menu .sc_header .sc_time{text-align:center;border-left:solid 1px #fff;background:#555}
.jq-schedule .sc_menu .sc_header_cell,.jq-schedule .sc_data{float:left;font-weight:bold;color:#fff;background:#555;position:relative}
.jq-schedule .sc_menu .sc_header_scroll,.jq-schedule .sc_data .sc_data_scroll{position:absolute;left:0;top:0}
.jq-schedule .sc_menu .sc_header_cell,.jq-schedule .sc_header .sc_time,.jq-schedule .sc_main_scroll .sc_time{color:#fff;padding:0;line-height:26px;height:26px;display:block}
.jq-schedule .sc_header .sc_time,.jq-schedule .sc_main_scroll .sc_time{float:left}
.jq-schedule .sc_main_box,.jq-schedule .sc_data{max-height:500px;overflow:hidden}
.jq-schedule .sc_main_box{float:left;overflow-x:auto;overflow-y:auto}
.jq-schedule .sc_main{position:relative}.jq-schedule .timeline{position:relative}
.jq-schedule .ui-draggable-dragging,.jq-schedule .ui-resizeable{z-index:20}
.jq-schedule .sc_bar{position:absolute;color:#fff;background:#4f93d6;cursor:pointer;z-index:10}
.jq-schedule .sc_bar .head{display:block;margin-top:6px;font-size:12px;padding:0 14px;height:1.2em;overflow:hidden}
.jq-schedule .sc_bar .text{display:block;margin-top:6px;font-weight:bold;padding:0 14px;height:1.2em;overflow:hidden}
.jq-schedule .sc_bar .ui-resizable-handle{display:block;content:" ";position:absolute;height:100%;right:0;top:0;width:5px;background:#2e7ac4}
.jq-schedule .sc_bar .ui-resizable-handle.ui-resizable-e{right:0}
.jq-schedule .sc_bar .ui-resizable-handle.ui-resizable-w{left:0}
.jq-schedule .timeline,.jq-schedule .sc_main .tb{border-bottom:solid 2px #666}
.jq-schedule .sc_data .timeline{overflow:hidden;padding:10px}
.jq-schedule .sc_data .timeline span{display:block}
.jq-schedule .sc_data .timeline span.timeline-subtitle{font-size:.8em;color:#ccc}
.jq-schedule .sc_main_scroll .sc_main .tl{float:left;height:100%;border-right:solid 1px #ccc}
.jq-schedule .sc_main_scroll .sc_main .tl:hover{background:#f0f0f0}
.jq-schedule .ui-state-disabled{opacity:1}
.jq-schedule .ui-state-disabled .ui-resizable-handle{display:none}
.jq-schedule .ui-state-disabled .ui-resizable-handle:hover{cursor:auto}
.jq-schedule .ui-draggable-disabled{opacity:.8}

        body {
            padding-top: 30px; /* 60px to make the container go all the way to the bottom of the topbar */
        }
        #logs{
            border: solid 1px #bbb;
            padding: 16px;
            background: #eee;
        }
        #logs .table{
            margin-bottom: 0;
        }
        #logs .table td,
        #logs .table th{
            border: none;
        }
        #schedule .sc_bar_insert{
            background-color: #ff678a;
        }
        #schedule .example2{
            background-color: #3eb698;
        }
        #schedule .example3{
            color: #2c0000;
            font-weight: bold;
            background-color: #c7ae50;
        }
        #schedule .sc_bar.sc_bar_photo .head,
        #schedule .sc_bar.sc_bar_photo .text{
            padding-left: 60px;
        }
        #schedule .sc_bar.sc_bar_photo .photo{
            position: absolute;
            left: 10px;
            top: 10px;
            width: 38px;
        }
        #schedule .sc_bar.sc_bar_photo .photo img{
            max-width: 100%;
        }
    </style>
</head>
<body>
<h1><a href="https://plnkr.co/plunk/FUeFIbTJsgSjAwEl" target="thebest">latest the best version is here</a></h1>

<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">jQ.Scuedule.js</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#home">Home</a></li>
                <li><a href="#demo">Demo</a></li>
                <li><a href="#info">Get Start</a></li>
                <li><a href="#option">Option</a></li>
            </ul>
        </div>
    </div>
</div>
<div class="container">
    <div class="jumbotron" style="padding-bottom: 16px; padding-top: 24px;">
        <h1 id="home" class="h2" style="padding-bottom: 16px"><a href=" https://plnkr.co/plunk/9tSKRGqNFMgrgBrH" target="mytimebar">Searching for a wifi switch scheduler that works on PC Phone and Tablet https://plnkr.co/plunk/9tSKRGqNFMgrgBrH</a><br>
jq.Schedule</h1>
        <p>javascriptbase time schedule  plugin.</p>
        <p>
            Drag and Drop Support/Resize Schedule/Ajax Support(Callback Event Option)
        </p>
        <div style="padding-bottom: 16px"><button onclick="javascript:location.href='https://github.com/ateliee/jquery.schedule';" class="btn btn-lg btn-primary" type="button">Download jq.Schedule</button></div>
        <div>
            <iframe src="https://ghbtns.com/github-btn.html?user=ateliee&repo=jquery.schedule&type=star&count=true&size=large" frameborder="0" scrolling="0" width="140px" height="30px"></iframe>
            <iframe src="https://ghbtns.com/github-btn.html?user=ateliee&repo=jquery.schedule&type=watch&count=true&size=large&v=2" frameborder="0" scrolling="0" width="140px" height="30px"></iframe>
        </div>
    </div>
    <h2 id="demo">Demo</h2>
    <p>
        Example Sample Demo
    </p>
    <h3>Method</h3>
    <div style="padding: 0 0 12px;">
        <button id="event_timelineData" class="btn btn-info" style="margin-bottom: 12px;">timelineData()</button>
        <button id="event_scheduleData" class="btn btn-info" style="margin-bottom: 12px;">scheduleData()</button>
        <button id="event_setDraggable" class="btn btn-info" style="margin-bottom: 12px;">toggleDraggable</button>
        <button id="event_setResizable" class="btn btn-info" style="margin-bottom: 12px;">toggleResizable</button>
        <button id="event_resetData" class="btn btn-danger" style="margin-bottom: 12px;">resetData()</button>
        <button id="event_resetRowData" class="btn btn-danger" style="margin-bottom: 12px;">resetRowData()</button>
    </div>
    <h3>Ajax</h3>
    <div style="padding: 0 0 12px;">
        <button class="btn btn-info ajax-data" data-target="1.json" style="margin-bottom: 12px;">ajax1()</button>
        <button class="btn btn-info ajax-data" data-target="2.json" style="margin-bottom: 12px;">ajax2()</button>
        <button class="btn btn-info ajax-data" data-target="3.json" style="margin-bottom: 12px;">ajax3()</button>
    </div>
    <div style="padding: 0 0 40px;">
        <div id="schedule"></div>
        <div class="row">
            <div class="col-md-8">
                <h3>Log</h3>
            </div>
            <div class="col-md-4 text-right">
                <a class="btn btn-default" style="margin-top: 16px;" id="clear-logs">clear</a>
            </div>
        </div>
        <div style="padding: 12px 0 0;">
            <div id="logs" class="table-responsive"></div>
        </div>
    </div>
    <h2 id="info">Get Start</h2>
    <ol>
        <li><p>Please Download <a href="https://github.com/ateliee/jquery.schedule/archive/master.zip">jQuery.Schedule</a></p></li>
        <li>
            <p>include <code>jquery.js</code>and<code>jquery.ui.js</code> after jq.schedule</p>
            <pre><code>&lt;script src=&quot;jquery-3.4.1.js&quot; type=&quot;text/javascript&quot; language=&quot;javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;jquery-ui-2.3.2.js&quot; type=&quot;text/javascript&quot; language=&quot;javascript&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../dist/js/jq.schedule.js&quot;&gt;&lt;/script&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;../dist/css/style.min.css&quot; /&gt;</code></pre>
        </li>
        <li>
            <p>init scripts</p>
            <pre><code>&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
    var $sc = jQuery(&quot;#schedule&quot;).timeSchedule($options);
});
&lt;/script&gt;</code></pre>
        </li>
    </ol>

    <h2 id="option">Option</h2>
    <div class="p">
        <table class="table table-striped">
            <tr>
                <th colspan="2">name</th>
                <th width="80">Type</th>
                <th>description</th>
            </tr>
            <tr>
                <td colspan="2">className</td>
                <td>String</td>
                <td>add elemnt class(default jq.schedule)</td>
            </tr>
            <tr>
                <td colspan="2">startTime</td>
                <td>String(HH:ii)</td>
                <td>schedule start time</td>
            </tr>
            <tr>
                <td colspan="2">endTime</td>
                <td>String(HH:ii)</td>
                <td>schedule end time</td>
            </tr>
            <tr>
                <td colspan="2">widthTime</td>
                <td>Integer</td>
                <td>minuite time line cell</td>
            </tr>
            <tr>
                <td colspan="2">timeLineY</td>
                <td>Integer</td>
                <td>cell height px</td>
            </tr>
            <tr>
                <td colspan="2">verticalScrollbar</td>
                <td>Integer</td>
                <td>scrollbar (px)</td>
            </tr>
            <tr>
                <td colspan="2">timeLineBorder</td>
                <td>Integer</td>
                <td>border(top and bottom)</td>
            </tr>
            <tr>
                <td colspan="2">bundleMoveWidth</td>
                <td>Integer</td>
                <td>width to move all schedules to the right of the clicked time line cell.
                </td>
            </tr>
            <tr>
                <td colspan="2">draggable</td>
                <td>Boolean</td>
                <td>enable draggable</td>
            </tr>
            <tr>
                <td colspan="2">resizable</td>
                <td>Boolean</td>
                <td>enable resizable</td>
            </tr>
            <tr>
                <td colspan="2">resizableLeft</td>
                <td>Boolean</td>
                <td>enable left handle resizable(default false)</td>
            </tr>
            <tr>
                <td rowspan="3">rows</td>
                <td></td>
                <td>Array</td>
                <td>Schedule Data</td>
            </tr>
            <tr>
                <td>title</td>
                <td>String</td>
                <td>Schedule Left Cell Text</td>
            </tr>
            <tr>
                <td>subtitle</td>
                <td>String(Option)</td>
                <td>Schedule Left Cell Sub Text</td>
            </tr>
            <tr>
                <td>schedule</td>
                <td>Array</td>
                <td>Schedule Cell Data</td>
            </tr>
            <tr>
                <td colspan="2">onInitRow</td>
                <td>function</td>
                <td>callback init time</td>
            </tr>
            <tr>
                <td colspan="2">onChange</td>
                <td>function</td>
                <td>callback change time</td>
            </tr>
            <tr>
                <td colspan="2">onClick</td>
                <td>function</td>
                <td>callback click time</td>
            </tr>
            <tr>
                <td colspan="2">onScheduleClick</td>
                <td>function</td>
                <td>callback timebar click</td>
            </tr>
            <tr>
                <td colspan="2">onAppendRow</td>
                <td>function</td>
                <td>callback append time</td>
            </tr>
            <tr>
                <td colspan="2">onAppendSchedule</td>
                <td>function</td>
                <td>callback append time data</td>
            </tr>
        </table>
    </div>

    <h2 id="data">Schedule Data</h2>
    <div>
        <table class="table table-striped">
            <tr>
                <th colspan="2">name</th>
                <th width="80">Type</th>
                <th>description</th>
            </tr>
            <tr>
                <td colspan="2">title</td>
                <td>String</td>
                <td>Visible Text Schedule Bar</td>
            </tr>
            <tr>
                <td colspan="2">class</td>
                <td>String</td>
                <td>add class name</td>
            </tr>
            <tr>
                <td rowspan="5">schedule</td>
                <td colspan="2">array</td>
                <td>add schedule data</td>
            </tr>
            <tr>
                <td>start</td>
                <td>String</td>
                <td>time String(HH:ii)</td>
            </tr>
            <tr>
                <td>end</td>
                <td>String</td>
                <td>time String(HH:ii)</td>
            </tr>
            <tr>
                <td>text</td>
                <td>String</td>
                <td>Show Text</td>
            </tr>
            <tr>
                <td>data</td>
                <td>Object,Array</td>
                <td>callback data Object</td>
            </tr>
        </table>
    </div>
</div>


<div id="footer">
    <div class="container">
        <p class="muted credit">Copyright © 2014 <a href="https://github.com/ateliee" target="_blank">ateliee</a> inc. All Rights Reserved.</p>
    </div>
</div>

<script
        src="https://code.jquery.com/jquery-3.4.1.min.js"
        integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
        crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.min.js" type="text/javascript" language="javascript"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>


<script >
"use strict";

function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }

(function ($) {
  'use strict';

  var PLUGIN_NAME = 'jqSchedule';
  var methods = {
    /**
     *
     * @param {string} str
     * @returns {number}
     */
    calcStringTime: function calcStringTime(str) {
      var slice = str.split(':');
      var h = Number(slice[0]) * 60 * 60;
      var i = Number(slice[1]) * 60;
      return h + i;
    },

    /**
     *
     * @param {number} val
     * @returns {string}
     */
    formatTime: function formatTime(val) {
      var i1 = val % 3600;
      var h = '' + Math.floor(val / 36000) + Math.floor(val / 3600 % 10);
      var i = '' + Math.floor(i1 / 600) + Math.floor(i1 / 60 % 10);
      return h + ':' + i;
    },

    /**
     * 設定データの保存
     *
     * @param {Options} data
     * @returns {*}
     */
    _saveSettingData: function _saveSettingData(data) {
      return this.data(PLUGIN_NAME + 'Setting', data);
    },

    /**
     * 設定データの取得
     *
     * @returns Options
     */
    _loadSettingData: function _loadSettingData() {
      return this.data(PLUGIN_NAME + 'Setting');
    },

    /**
     * 保存データの保存
     *
     * @param {SaveData} data
     * @returns {*}
     */
    _saveData: function _saveData(data) {
      var d = $.extend({
        tableStartTime: 0,
        tableEndTime: 0,
        schedule: [],
        timeline: []
      }, data);
      return this.data(PLUGIN_NAME, d);
    },

    /**
     * 保存データの取得
     *
     * @returns SaveData
     */
    _loadData: function _loadData() {
      return this.data(PLUGIN_NAME);
    },

    /**
     * スケジュールの取得
     *
     * @returns ScheduleData[]
     */
    scheduleData: function scheduleData() {
      var $this = $(this);

      var saveData = methods._loadData.apply($this);

      if (saveData) {
        return saveData.schedule;
      }

      return [];
    },

    /**
     * get timelineData
     * @returns {any[]}
     */
    timelineData: function timelineData() {
      var $this = $(this);

      var saveData = methods._loadData.apply($this);

      var data = [];
      var i;

      for (i in saveData.timeline) {
        data[i] = saveData.timeline[i];
        data[i].schedule = [];
      }

      for (i in saveData.schedule) {
        var d = saveData.schedule[i];

        if (typeof d.timeline === 'undefined') {
          continue;
        }

        if (typeof data[d.timeline] === 'undefined') {
          continue;
        }

        data[d.timeline].schedule.push(d);
      }

      return data;
    },

    /**
     * reset data
     */
    resetData: function resetData() {
      return this.each(function () {
        var $this = $(this);

        var saveData = methods._loadData.apply($this);

        saveData.schedule = [];

        methods._saveData.apply($this, [saveData]);

        $this.find('.sc_bar').remove();

        for (var i in saveData.timeline) {
          saveData.timeline[i].schedule = [];

          methods._resizeRow.apply($this, [i, 0]);
        }

        methods._saveData.apply($this, [saveData]);
      });
    },

    /**
     * add schedule data
     *
     * @param {number} timeline
     * @param {object} data
     * @returns {methods}
     */
    addSchedule: function addSchedule(timeline, data) {
      return this.each(function () {
        var $this = $(this);
        var d = {
          start: data.start,
          end: data.end,
          startTime: methods.calcStringTime(data.start),
          endTime: methods.calcStringTime(data.end),
          text: data.text,
          timeline: timeline
        };

        if (data.data) {
          d.data = data.data;
        }

        methods._addScheduleData.apply($this, [timeline, d]);

        methods._resetBarPosition.apply($this, [timeline]);
      });
    },

    /**
     * add schedule data
     *
     * @param {number} timeline
     * @param {object} data
     * @returns {methods}
     */
    addRow: function addRow(timeline, data) {
      return this.each(function () {
        var $this = $(this);

        methods._addRow.apply($this, [timeline, data]);
      });
    },

    /**
     * clear row
     *
     * @returns {methods}
     */
    resetRowData: function resetRowData() {
      return this.each(function () {
        var $this = $(this);

        var data = methods._loadData.apply($this);

        data.schedule = [];
        data.timeline = [];

        methods._saveData.apply($this, [data]);

        $this.find('.sc_bar').remove();
        $this.find('.timeline').remove();
        $this.find('.sc_data').height(0);
      });
    },

    /**
     * clear row
     *
     * @param {object} data
     * @returns {methods}
     */
    setRows: function setRows(data) {
      return this.each(function () {
        var $this = $(this);
        methods.resetRowData.apply($this, []);

        for (var timeline in data) {
          methods.addRow.apply($this, [timeline, data[timeline]]);
        }
      });
    },

    /**
     * switch draggable
     * @param {boolean} enable
     */
    setDraggable: function setDraggable(enable) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        if (enable !== setting.draggable) {
          setting.draggable = enable;

          methods._saveSettingData.apply($this, setting);

          if (enable) {
            $this.find('.sc_bar').draggable('enable');
          } else {
            $this.find('.sc_bar').draggable('disable');
          }
        }
      });
    },

    /**
     * switch resizable
     * @param {boolean} enable
     */
    setResizable: function setResizable(enable) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        if (enable !== setting.resizable) {
          setting.resizable = enable;

          methods._saveSettingData.apply($this, setting);

          if (enable) {
            $this.find('.sc_bar').resizable('enable');
          } else {
            $this.find('.sc_bar').resizable('disable');
          }
        }
      });
    },

    /**
     * 現在のタイムライン番号を取得
     *
     * @param node
     * @param top
     * @returns {number}
     */
    _getTimeLineNumber: function _getTimeLineNumber(node, top) {
      var $this = $(this);

      var setting = methods._loadSettingData.apply($this);

      var num = 0;
      var n = 0;
      var tn = Math.ceil(top / (setting.timeLineY + setting.timeLinePaddingTop + setting.timeLinePaddingBottom));

      for (var i in setting.rows) {
        var r = setting.rows[i];
        var tr = 0;

        if (_typeof(r.schedule) === 'object') {
          tr = r.schedule.length;
        }

        if (node && node.timeline) {
          tr++;
        }

        n += Math.max(tr, 1);

        if (n >= tn) {
          break;
        }

        num++;
      }

      return num;
    },

    /**
     * 背景データ追加
     *
     * @param {ScheduleData} data
     */
    _addScheduleBgData: function _addScheduleBgData(data) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var saveData = methods._loadData.apply($this);

        var st = Math.ceil((data.startTime - saveData.tableStartTime) / setting.widthTime);
        var et = Math.floor((data.endTime - saveData.tableStartTime) / setting.widthTime);
        var $bar = $('<div class="sc_bgBar"><span class="text"></span></div>');
        $bar.css({
          left: st * setting.widthTimeX,
          top: 0,
          width: (et - st) * setting.widthTimeX,
          height: $this.find('.sc_main .timeline').eq(data.timeline).height()
        });

        if (data.text) {
          $bar.find('.text').text(data.text);
        }

        if (data.class) {
          $bar.addClass(data.class);
        } // $element.find('.sc_main').append($bar);


        $this.find('.sc_main .timeline').eq(data.timeline).append($bar);
      });
    },

    /**
     * スケジュール追加
     *
     * @param timeline
     * @param {ScheduleData} d
     * @returns {number}
     */
    _addScheduleData: function _addScheduleData(timeline, d) {
      var data = d;
      data.startTime = data.startTime ? data.startTime : methods.calcStringTime(data.start);
      data.endTime = data.endTime ? data.endTime : methods.calcStringTime(data.end);
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var saveData = methods._loadData.apply($this);

        var st = Math.ceil((data.startTime - saveData.tableStartTime) / setting.widthTime);
        var et = Math.floor((data.endTime - saveData.tableStartTime) / setting.widthTime);
        var $bar = $('<div class="sc_bar"><span class="head"><span class="time"></span></span><span class="text"></span></div>');
        var stext = methods.formatTime(data.startTime);
        var etext = methods.formatTime(data.endTime);

        var snum = methods._getScheduleCount.apply($this, [data.timeline]);

        $bar.css({
          left: st * setting.widthTimeX,
          top: snum * setting.timeLineY + setting.timeLinePaddingTop,
          width: (et - st) * setting.widthTimeX,
          height: setting.timeLineY
        });
        $bar.find('.time').text(stext + '-' + etext);

        if (data.text) {
          $bar.find('.text').text(data.text);
        }

        if (data.class) {
          $bar.addClass(data.class);
        } // $this.find('.sc_main').append($bar);


        var $row = $this.find('.sc_main .timeline').eq(timeline);
        $row.append($bar); // データの追加

        saveData.schedule.push(data);

        methods._saveData.apply($this, [saveData]); // コールバックがセットされていたら呼出


        if (setting.onAppendSchedule) {
          setting.onAppendSchedule.apply($this, [$bar, data]);
        } // key


        var key = saveData.schedule.length - 1;
        $bar.data('sc_key', key);
        $bar.on('mouseup', function () {
          // コールバックがセットされていたら呼出
          if (setting.onClick) {
            if ($(this).data('dragCheck') !== true && $(this).data('resizeCheck') !== true) {
              var $n = $(this);
              var scKey = $n.data('sc_key');
              setting.onClick.apply($this, [$n, saveData.schedule[scKey]]);
            }
          }
        });
        var $node = $this.find('.sc_bar');
        var currentNode = null; // move node.

        $node.draggable({
          grid: [setting.widthTimeX, 1],
          containment: $this.find('.sc_main'),
          helper: 'original',
          start: function start(event, ui) {
            var node = {};
            node.node = this;
            node.offsetTop = ui.position.top;
            node.offsetLeft = ui.position.left;
            node.currentTop = ui.position.top;
            node.currentLeft = ui.position.left;
            node.timeline = methods._getTimeLineNumber.apply($this, [currentNode, ui.position.top]);
            node.nowTimeline = node.timeline;
            currentNode = node;
          },

          /**
           *
           * @param {Event} event
           * @param {function} ui
           * @returns {boolean}
           */
          drag: function drag(event, ui) {
            $(this).data('dragCheck', true);

            if (!currentNode) {
              return false;
            }

            var $moveNode = $(this);
            var scKey = $moveNode.data('sc_key');

            var timelineNum = methods._getTimeLineNumber.apply($this, [currentNode, ui.position.top]); // eslint-disable-next-line no-param-reassign


            ui.position.left = Math.floor(ui.position.left / setting.widthTimeX) * setting.widthTimeX;

            if (currentNode.nowTimeline !== timelineNum) {
              // 現在のタイムライン
              currentNode.nowTimeline = timelineNum;
            }

            currentNode.currentTop = ui.position.top;
            currentNode.currentLeft = ui.position.left; // テキスト変更

            methods._rewriteBarText.apply($this, [$moveNode, saveData.schedule[scKey]]);

            return true;
          },
          // 要素の移動が終った後の処理
          stop: function stop() {
            $(this).data('dragCheck', false);
            currentNode = null;
            var $n = $(this);
            var scKey = $n.data('sc_key');
            var x = $n.position().left; // var w = $n.width();

            var start = saveData.tableStartTime + Math.floor(x / setting.widthTimeX) * setting.widthTime; // var end = saveData.tableStartTime + (Math.floor((x + w) / setting.widthTimeX) * setting.widthTime);

            var end = start + (saveData.schedule[scKey].endTime - saveData.schedule[scKey].startTime);
            saveData.schedule[scKey].start = methods.formatTime(start);
            saveData.schedule[scKey].end = methods.formatTime(end);
            saveData.schedule[scKey].startTime = start;
            saveData.schedule[scKey].endTime = end; // コールバックがセットされていたら呼出

            if (setting.onChange) {
              setting.onChange.apply($this, [$n, saveData.schedule[scKey]]);
            }
          }
        });
        var resizableHandles = ['e'];

        if (setting.resizableLeft) {
          resizableHandles.push('w');
        }

        $node.resizable({
          handles: resizableHandles.join(','),
          grid: [setting.widthTimeX, setting.timeLineY - setting.timeBorder],
          minWidth: setting.widthTimeX,
          containment: $this.find('.sc_main_scroll'),
          start: function start() {
            var $n = $(this);
            $n.data('resizeCheck', true);
          },
          resize: function resize(ev, ui) {
            // box-sizing: border-box; に対応
            ui.element.height(ui.size.height);
            ui.element.width(ui.size.width);
          },
          // 要素の移動が終った後の処理
          stop: function stop() {
            var $n = $(this);
            var scKey = $n.data('sc_key');
            var x = $n.position().left;
            var w = $n.outerWidth();
            var start = saveData.tableStartTime + Math.floor(x / setting.widthTimeX) * setting.widthTime;
            var end = saveData.tableStartTime + Math.floor((x + w) / setting.widthTimeX) * setting.widthTime;
            var timelineNum = saveData.schedule[scKey].timeline;
            saveData.schedule[scKey].start = methods.formatTime(start);
            saveData.schedule[scKey].end = methods.formatTime(end);
            saveData.schedule[scKey].startTime = start;
            saveData.schedule[scKey].endTime = end; // 高さ調整

            methods._resetBarPosition.apply($this, [timelineNum]); // テキスト変更


            methods._rewriteBarText.apply($this, [$n, saveData.schedule[scKey]]);

            $n.data('resizeCheck', false); // コールバックがセットされていたら呼出

            if (setting.onChange) {
              setting.onChange.apply($this, [$n, saveData.schedule[scKey]]);
            }
          }
        });

        if (setting.draggable === false) {
          $node.draggable('disable');
        }

        if (setting.resizable === false) {
          $node.resizable('disable');
        }

        return key;
      });
    },

    /**
     * スケジュール数の取得
     *
     * @param {number} n row number
     * @returns {number}
     */
    _getScheduleCount: function _getScheduleCount(n) {
      var $this = $(this);

      var saveData = methods._loadData.apply($this);

      var num = 0;

      for (var i in saveData.schedule) {
        if (saveData.schedule[i].timeline === n) {
          num++;
        }
      }

      return num;
    },

    /**
     * add rows
     *
     * @param timeline
     * @param row
     */
    _addRow: function _addRow(timeline, row) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var saveData = methods._loadData.apply($this);

        var id = $this.find('.sc_main .timeline').length;
        var html;
        html = '';
        html += '<div class="timeline"></div>';
        var $data = $(html);

        if (row.title) {
          $data.append('<span class="timeline-title">' + row.title + '</span>');
        }

        if (row.subtitle) {
          $data.append('<span class="timeline-subtitle">' + row.subtitle + '</span>');
        } // event call


        if (setting.onInitRow) {
          setting.onInitRow.apply($this, [$data, row]);
        }

        $this.find('.sc_data_scroll').append($data);
        html = '';
        html += '<div class="timeline"></div>';
        var $timeline = $(html);

        for (var t = saveData.tableStartTime; t < saveData.tableEndTime; t += setting.widthTime) {
          var $tl = $('<div class="tl"></div>');
          $tl.outerWidth(setting.widthTimeX);
          $tl.data('time', methods.formatTime(t));
          $tl.data('timeline', timeline);
          $timeline.append($tl);
        } // クリックイベント
        // left click


        $timeline.find('.tl').on('click', function () {
          if (setting.onScheduleClick) {
            setting.onScheduleClick.apply($this, [this, $(this).data('time'), $(this).data('timeline'), saveData.timeline[$(this).data('timeline')]]);
          }
        }); // right click

        $timeline.find('.tl').on('contextmenu', function () {
          if (setting.onScheduleClick) {
            setting.onScheduleClick.apply($this, [this, $(this).data('time'), $(this).data('timeline'), saveData.timeline[$(this).data('timeline')]]);
          }

          return false;
        });
        $this.find('.sc_main').append($timeline);
        saveData.timeline[timeline] = row;

        methods._saveData.apply($this, [saveData]);

        if (row.class && row.class !== '') {
          $this.find('.sc_data .timeline').eq(id).addClass(row.class);
          $this.find('.sc_main .timeline').eq(id).addClass(row.class);
        } // スケジュールタイムライン


        if (row.schedule) {
          for (var i in row.schedule) {
            var bdata = row.schedule[i];
            var s = bdata.start ? bdata.start : methods.calcStringTime(bdata.startTime);
            var e = bdata.end ? bdata.end : methods.calcStringTime(bdata.endTime);
            var data = {};
            data.start = s;
            data.end = e;

            if (bdata.text) {
              data.text = bdata.text;
            }

            data.timeline = timeline;
            data.data = {};

            if (bdata.data) {
              data.data = bdata.data;
            }

            methods._addScheduleData.apply($this, [id, data]);
          }
        } // 高さの調整


        methods._resetBarPosition.apply($this, [id]);

        $this.find('.sc_main .timeline').eq(id).droppable({
          accept: '.sc_bar',
          drop: function drop(ev, ui) {
            var node = ui.draggable;
            var scKey = node.data('sc_key');
            var nowTimelineNum = saveData.schedule[scKey].timeline;
            var timelineNum = $this.find('.sc_main .timeline').index(this); // タイムラインの変更

            saveData.schedule[scKey].timeline = timelineNum;
            node.appendTo(this); // 高さ調整

            methods._resetBarPosition.apply($this, [nowTimelineNum]);

            methods._resetBarPosition.apply($this, [timelineNum]);
          }
        }); // コールバックがセットされていたら呼出

        if (setting.onAppendRow) {
          $this.find('.sc_main .timeline').eq(id).find('.sc_bar').each(function () {
            var $n = $(this);
            var scKey = $n.data('sc_key');
            setting.onAppendRow.apply($this, [$n, saveData.schedule[scKey]]);
          });
        }
      });
    },

    /**
     * テキストの変更
     *
     * @param {jQuery} node
     * @param {Object} data
     */
    _rewriteBarText: function _rewriteBarText(node, data) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var saveData = methods._loadData.apply($this);

        var x = node.position().left; // var w = node.width();

        var start = saveData.tableStartTime + Math.floor(x / setting.widthTimeX) * setting.widthTime; // var end = saveData.tableStartTime + (Math.floor((x + w) / setting.widthTimeX) * setting.widthTime);

        var end = start + (data.endTime - data.startTime);
        var html = methods.formatTime(start) + '-' + methods.formatTime(end);
        $(node).find('.time').html(html);
      });
    },

    /**
     *
     * @param {Number} n
     */
    _resetBarPosition: function _resetBarPosition(n) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this); // 要素の並び替え


        var $barList = $this.find('.sc_main .timeline').eq(n).find('.sc_bar');
        var codes = [],
            check = [];
        var h = 0;
        var $e1, $e2;
        var c1, c2, s1, s2, e1, e2;
        var i;

        for (i = 0; i < $barList.length; i++) {
          codes[i] = {
            code: i,
            x: $($barList[i]).position().left
          };
        } // ソート


        codes.sort(function (a, b) {
          if (a.x < b.x) {
            return -1;
          }

          if (a.x > b.x) {
            return 1;
          }

          return 0;
        });

        for (i = 0; i < codes.length; i++) {
          c1 = codes[i].code;
          $e1 = $($barList[c1]);

          for (h = 0; h < check.length; h++) {
            var next = false;

            for (var j = 0; j < check[h].length; j++) {
              c2 = check[h][j];
              $e2 = $($barList[c2]);
              s1 = $e1.position().left;
              e1 = $e1.position().left + $e1.outerWidth();
              s2 = $e2.position().left;
              e2 = $e2.position().left + $e2.outerWidth();

              if (s1 < e2 && e1 > s2) {
                next = true;
                continue;
              }
            }

            if (!next) {
              break;
            }
          }

          if (!check[h]) {
            check[h] = [];
          }

          $e1.css({
            top: h * setting.timeLineY + setting.timeLinePaddingTop
          });
          check[h][check[h].length] = c1;
        } // 高さの調整


        methods._resizeRow.apply($this, [n, check.length]);
      });
    },

    /**
     *
     * @param n
     * @param height
     */
    _resizeRow: function _resizeRow(n, height) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var h = Math.max(height, 1);
        $this.find('.sc_data .timeline').eq(n).outerHeight(h * setting.timeLineY + setting.timeLineBorder + setting.timeLinePaddingTop + setting.timeLinePaddingBottom);
        $this.find('.sc_main .timeline').eq(n).outerHeight(h * setting.timeLineY + setting.timeLineBorder + setting.timeLinePaddingTop + setting.timeLinePaddingBottom);
        $this.find('.sc_main .timeline').eq(n).find('.sc_bgBar').each(function () {
          $(this).outerHeight($(this).closest('.timeline').outerHeight());
        });
        $this.find('.sc_data').outerHeight($this.find('.sc_main_box').outerHeight());
      });
    },

    /**
     * resizeWindow
     */
    _resizeWindow: function _resizeWindow() {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var saveData = methods._loadData.apply($this);

        var scWidth = $this.width();
        var scMainWidth = scWidth - setting.dataWidth - setting.verticalScrollbar;
        var cellNum = Math.floor((saveData.tableEndTime - saveData.tableStartTime) / setting.widthTime);
        $this.find('.sc_header_cell').width(setting.dataWidth);
        $this.find('.sc_data,.sc_data_scroll').width(setting.dataWidth);
        $this.find('.sc_header').width(scMainWidth);
        $this.find('.sc_main_box').width(scMainWidth);
        $this.find('.sc_header_scroll').width(setting.widthTimeX * cellNum);
        $this.find('.sc_main_scroll').width(setting.widthTimeX * cellNum);
      });
    },

    /**
     * move all cells of the right of the specified time line cell
     *
     * @param timeline
     * @param baseTimeLineCell
     * @param moveWidth
     */
    _moveSchedules: function _moveSchedules(timeline, baseTimeLineCell, moveWidth) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var saveData = methods._loadData.apply($this);

        var $barList = $this.find('.sc_main .timeline').eq(timeline).find('.sc_bar');

        for (var i = 0; i < $barList.length; i++) {
          var $bar = $($barList[i]);

          if (baseTimeLineCell.position().left <= $bar.position().left) {
            var v1 = $bar.position().left + setting.widthTimeX * moveWidth;
            var v2 = Math.floor((saveData.tableEndTime - saveData.tableStartTime) / setting.widthTime) * setting.widthTimeX - $bar.outerWidth();
            $bar.css({
              left: Math.max(0, Math.min(v1, v2))
            });
            var scKey = $bar.data('sc_key');
            var start = saveData.tableStartTime + Math.floor($bar.position().left / setting.widthTimeX) * setting.widthTime;
            var end = start + (saveData.schedule[scKey].end - saveData.schedule[scKey].start);
            saveData.schedule[scKey].start = methods.formatTime(start);
            saveData.schedule[scKey].end = methods.formatTime(end);
            saveData.schedule[scKey].startTime = start;
            saveData.schedule[scKey].endTime = end;

            methods._rewriteBarText.apply($this, [$bar, saveData.schedule[scKey]]); // if setting


            if (setting.onChange) {
              setting.onChange.apply($this, [$bar, saveData.schedule[scKey]]);
            }
          }
        }

        methods._resetBarPosition.apply($this, [timeline]);
      });
    },

    /**
     * initialize
     */
    init: function init(options) {
      return this.each(function () {
        var $this = $(this);
        var config = $.extend({
          className: 'jq-schedule',
          rows: {},
          startTime: '07:00',
          endTime: '19:30',
          widthTimeX: 25,
          // 1cell辺りの幅(px)
          widthTime: 600,
          // 区切り時間(秒)
          timeLineY: 50,
          // timeline height(px)
          timeLineBorder: 1,
          // timeline height border
          timeBorder: 1,
          // border width
          timeLinePaddingTop: 0,
          timeLinePaddingBottom: 0,
          headTimeBorder: 1,
          // time border width
          dataWidth: 90,
          // data width
          verticalScrollbar: 0,
          // vertical scrollbar width
          bundleMoveWidth: 1,
          // width to move all schedules to the right of the clicked time cell
          draggable: true,
          resizable: true,
          resizableLeft: false,
          // event
          onInitRow: null,
          onChange: null,
          onClick: null,
          onAppendRow: null,
          onAppendSchedule: null,
          onScheduleClick: null
        }, options);

        methods._saveSettingData.apply($this, [config]);

        var tableStartTime = methods.calcStringTime(config.startTime);
        var tableEndTime = methods.calcStringTime(config.endTime);
        tableStartTime -= tableStartTime % config.widthTime;
        tableEndTime -= tableEndTime % config.widthTime;

        methods._saveData.apply($this, [{
          tableStartTime: tableStartTime,
          tableEndTime: tableEndTime
        }]);

        var html = '' + '<div class="sc_menu">' + '\n' + '<div class="sc_header_cell"><span>&nbsp;</span></div>' + '\n' + '<div class="sc_header">' + '\n' + '<div class="sc_header_scroll"></div>' + '\n' + '</div>' + '\n' + '</div>' + '\n' + '<div class="sc_wrapper">' + '\n' + '<div class="sc_data">' + '\n' + '<div class="sc_data_scroll"></div>' + '\n' + '</div>' + '\n' + '<div class="sc_main_box">' + '\n' + '<div class="sc_main_scroll">' + '\n' + '<div class="sc_main"></div>' + '\n' + '</div>' + '\n' + '</div>' + '\n' + '</div>';
        $this.append(html);
        $this.addClass(config.className);
        $this.find('.sc_main_box').on('scroll', function () {
          $this.find('.sc_data_scroll').css('top', $(this).scrollTop() * -1);
          $this.find('.sc_header_scroll').css('left', $(this).scrollLeft() * -1);
        }); // add time cell
        // var cellNum = Math.floor((tableEndTime - tableStartTime) / config.widthTime);

        var beforeTime = -1;

        for (var t = tableStartTime; t < tableEndTime; t += config.widthTime) {
          if (beforeTime < 0 || Math.floor(beforeTime / 3600) !== Math.floor(t / 3600)) {
            html = '';
            html += '<div class="sc_time">' + methods.formatTime(t) + '</div>';
            var $time = $(html);
            var cn = Number(Math.min(Math.ceil((t + config.widthTime) / 3600) * 3600, tableEndTime) - t);
            var cellNum = Math.floor(cn / config.widthTime);
            $time.width(cellNum * config.widthTimeX);
            $this.find('.sc_header_scroll').append($time);
            beforeTime = t;
          }
        }

        $(window).on('resize', function () {
          methods._resizeWindow.apply($this);
        }).trigger('resize'); // addrow

        for (var i in config.rows) {
          methods._addRow.apply($this, [i, config.rows[i]]);
        }
      });
    }
  };
  /**
   *
   * @param {Object|string} method
   * @returns {jQuery|methods|*}
   */
  // eslint-disable-next-line no-param-reassign

  $.fn.timeSchedule = function (method) {
    // Method calling logic
    if (methods[method]) {
      return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); // eslint-disable-next-line no-else-return
    } else if (_typeof(method) === 'object' || !method) {
      return methods.init.apply(this, arguments);
    }

    $.error('Method ' + method + ' does not exist on jQuery.timeSchedule');
    return this;
  };
})(jQuery);

</script>



<script type="text/javascript">
    function addLog(type, message){
        var $log = $('<tr />');
        $log.append($('<th />').text(type));
        $log.append($('<td />').text(message ? JSON.stringify(message) : ''));
        $("#logs table").prepend($log);
    }
    $(function(){
        $("#logs").append('<table class="table">');
        var isDraggable = true;
        var isResizable = true;
        var $sc = $("#schedule").timeSchedule({
            startTime: "07:00", // schedule start time(HH:ii)
            endTime: "21:00",   // schedule end time(HH:ii)
            widthTime: 60 * 10,  // cell timestamp example 10 minutes
            timeLineY: 60,       // height(px)
            verticalScrollbar: 20,   // scrollbar (px)
            timeLineBorder: 2,   // border(top and bottom)
            bundleMoveWidth: 6,  // width to move all schedules to the right of the clicked time line cell
            draggable: isDraggable,
            resizable: isResizable,
            resizableLeft: true,
            rows : {
                '0' : {
                    title : 'Monday',
                    schedule:[
                        {
                            start: '09:00',
                            end: '12:00',
                            text: 'Text Area',
                            data: {
                            }
                        },
                        {
                            start: '11:00',
                            end: '14:00',
                            text: 'Text Area',
                            data: {
                            }
                        }
                    ]
                },
                '1' : {
                    title : 'Tuesday',
                    schedule:[
                        {
                            start: '16:00',
                            end: '17:00',
                            text: 'Text Area',
                            data: {
                            }
                        }
                    ]
                },
                '2' : {
                    title : 'Wednesday',
                    schedule:[
                        {
                            start: '16:00',
                            end: '17:00',
                            text: 'Text Area',
                            data: {
                            }
                        }
                    ]
                }
            },
            onChange: function(node, data){
                addLog('onChange', data);
            },
            onInitRow: function(node, data){
                addLog('onInitRow', data);
            },
            onClick: function(node, data){
                addLog('onClick', data);
            },
            onAppendRow: function(node, data){
                addLog('onAppendRow', data);
            },
            onAppendSchedule: function(node, data){
                addLog('onAppendSchedule', data);
                if(data.data.class){
                    node.addClass(data.data.class);
                }
                if(data.data.image){
                    var $img = $('<div class="photo"><img></div>');
                    $img.find('img').attr('src', data.data.image);
                    node.prepend($img);
                    node.addClass('sc_bar_photo');
                }
            },
            onScheduleClick: function(node, time, timeline){
                var start = time;
                var end = $(this).timeSchedule('formatTime', $(this).timeSchedule('calcStringTime', time) + 3600);
                $(this).timeSchedule('addSchedule', timeline, {
                    start: start,
                    end: end,
                    text:'Insert Schedule',
                    data:{
                        class: 'sc_bar_insert'
                    }
                });
                addLog('onScheduleClick', time + ' ' + timeline);
            },
        });
        $('#event_timelineData').on('click', function(){
            addLog('timelineData', $sc.timeSchedule('timelineData'));
        });
        $('#event_scheduleData').on('click', function(){
            addLog('scheduleData', $sc.timeSchedule('scheduleData'));
        });
        $('#event_resetData').on('click', function(){
            $sc.timeSchedule('resetData');
            addLog('resetData');
        });
        $('#event_resetRowData').on('click', function(){
            $sc.timeSchedule('resetRowData');
            addLog('resetRowData');
        });
        $('#event_setDraggable').on('click', function(){
            isDraggable = !isDraggable;
            $sc.timeSchedule('setDraggable', isDraggable);
            addLog('setDraggable', isDraggable ? 'enable' : 'disable');
        });
        $('#event_setResizable').on('click', function(){
            isResizable = !isResizable;
            $sc.timeSchedule('setResizable', isResizable);
            addLog('setResizable', isResizable ? 'enable' : 'disable');
        });
        $('.ajax-data').on('click', function(){
            $.ajax({url: './data/'+$(this).attr('data-target')})
                .done( (data) => {
                    addLog('Ajax GetData', data);
                    $sc.timeSchedule('setRows', data);
                });
        });
        $('#clear-logs').on('click', function(){
            $('#logs .table').empty();
        });
    });
</script>
</body>
</html>
/* Add your styles here */

"use strict";

function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }

(function ($) {
  'use strict';

  var PLUGIN_NAME = 'jqSchedule';
  var methods = {
    /**
     *
     * @param {string} str
     * @returns {number}
     */
    calcStringTime: function calcStringTime(str) {
      var slice = str.split(':');
      var h = Number(slice[0]) * 60 * 60;
      var i = Number(slice[1]) * 60;
      return h + i;
    },

    /**
     *
     * @param {number} val
     * @returns {string}
     */
    formatTime: function formatTime(val) {
      var i1 = val % 3600;
      var h = '' + Math.floor(val / 36000) + Math.floor(val / 3600 % 10);
      var i = '' + Math.floor(i1 / 600) + Math.floor(i1 / 60 % 10);
      return h + ':' + i;
    },

    /**
     * 設定データの保存
     *
     * @param {Options} data
     * @returns {*}
     */
    _saveSettingData: function _saveSettingData(data) {
      return this.data(PLUGIN_NAME + 'Setting', data);
    },

    /**
     * 設定データの取得
     *
     * @returns Options
     */
    _loadSettingData: function _loadSettingData() {
      return this.data(PLUGIN_NAME + 'Setting');
    },

    /**
     * 保存データの保存
     *
     * @param {SaveData} data
     * @returns {*}
     */
    _saveData: function _saveData(data) {
      var d = $.extend({
        tableStartTime: 0,
        tableEndTime: 0,
        schedule: [],
        timeline: []
      }, data);
      return this.data(PLUGIN_NAME, d);
    },

    /**
     * 保存データの取得
     *
     * @returns SaveData
     */
    _loadData: function _loadData() {
      return this.data(PLUGIN_NAME);
    },

    /**
     * スケジュールの取得
     *
     * @returns ScheduleData[]
     */
    scheduleData: function scheduleData() {
      var $this = $(this);

      var saveData = methods._loadData.apply($this);

      if (saveData) {
        return saveData.schedule;
      }

      return [];
    },

    /**
     * get timelineData
     * @returns {any[]}
     */
    timelineData: function timelineData() {
      var $this = $(this);

      var saveData = methods._loadData.apply($this);

      var data = [];
      var i;

      for (i in saveData.timeline) {
        data[i] = saveData.timeline[i];
        data[i].schedule = [];
      }

      for (i in saveData.schedule) {
        var d = saveData.schedule[i];

        if (typeof d.timeline === 'undefined') {
          continue;
        }

        if (typeof data[d.timeline] === 'undefined') {
          continue;
        }

        data[d.timeline].schedule.push(d);
      }

      return data;
    },

    /**
     * reset data
     */
    resetData: function resetData() {
      return this.each(function () {
        var $this = $(this);

        var saveData = methods._loadData.apply($this);

        saveData.schedule = [];

        methods._saveData.apply($this, [saveData]);

        $this.find('.sc_bar').remove();

        for (var i in saveData.timeline) {
          saveData.timeline[i].schedule = [];

          methods._resizeRow.apply($this, [i, 0]);
        }

        methods._saveData.apply($this, [saveData]);
      });
    },

    /**
     * add schedule data
     *
     * @param {number} timeline
     * @param {object} data
     * @returns {methods}
     */
    addSchedule: function addSchedule(timeline, data) {
      return this.each(function () {
        var $this = $(this);
        var d = {
          start: data.start,
          end: data.end,
          startTime: methods.calcStringTime(data.start),
          endTime: methods.calcStringTime(data.end),
          text: data.text,
          timeline: timeline
        };

        if (data.data) {
          d.data = data.data;
        }

        methods._addScheduleData.apply($this, [timeline, d]);

        methods._resetBarPosition.apply($this, [timeline]);
      });
    },

    /**
     * add schedule data
     *
     * @param {number} timeline
     * @param {object} data
     * @returns {methods}
     */
    addRow: function addRow(timeline, data) {
      return this.each(function () {
        var $this = $(this);

        methods._addRow.apply($this, [timeline, data]);
      });
    },

    /**
     * clear row
     *
     * @returns {methods}
     */
    resetRowData: function resetRowData() {
      return this.each(function () {
        var $this = $(this);

        var data = methods._loadData.apply($this);

        data.schedule = [];
        data.timeline = [];

        methods._saveData.apply($this, [data]);

        $this.find('.sc_bar').remove();
        $this.find('.timeline').remove();
        $this.find('.sc_data').height(0);
      });
    },

    /**
     * clear row
     *
     * @param {object} data
     * @returns {methods}
     */
    setRows: function setRows(data) {
      return this.each(function () {
        var $this = $(this);
        methods.resetRowData.apply($this, []);

        for (var timeline in data) {
          methods.addRow.apply($this, [timeline, data[timeline]]);
        }
      });
    },

    /**
     * switch draggable
     * @param {boolean} enable
     */
    setDraggable: function setDraggable(enable) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        if (enable !== setting.draggable) {
          setting.draggable = enable;

          methods._saveSettingData.apply($this, setting);

          if (enable) {
            $this.find('.sc_bar').draggable('enable');
          } else {
            $this.find('.sc_bar').draggable('disable');
          }
        }
      });
    },

    /**
     * switch resizable
     * @param {boolean} enable
     */
    setResizable: function setResizable(enable) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        if (enable !== setting.resizable) {
          setting.resizable = enable;

          methods._saveSettingData.apply($this, setting);

          if (enable) {
            $this.find('.sc_bar').resizable('enable');
          } else {
            $this.find('.sc_bar').resizable('disable');
          }
        }
      });
    },

    /**
     * 現在のタイムライン番号を取得
     *
     * @param node
     * @param top
     * @returns {number}
     */
    _getTimeLineNumber: function _getTimeLineNumber(node, top) {
      var $this = $(this);

      var setting = methods._loadSettingData.apply($this);

      var num = 0;
      var n = 0;
      var tn = Math.ceil(top / (setting.timeLineY + setting.timeLinePaddingTop + setting.timeLinePaddingBottom));

      for (var i in setting.rows) {
        var r = setting.rows[i];
        var tr = 0;

        if (_typeof(r.schedule) === 'object') {
          tr = r.schedule.length;
        }

        if (node && node.timeline) {
          tr++;
        }

        n += Math.max(tr, 1);

        if (n >= tn) {
          break;
        }

        num++;
      }

      return num;
    },

    /**
     * 背景データ追加
     *
     * @param {ScheduleData} data
     */
    _addScheduleBgData: function _addScheduleBgData(data) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var saveData = methods._loadData.apply($this);

        var st = Math.ceil((data.startTime - saveData.tableStartTime) / setting.widthTime);
        var et = Math.floor((data.endTime - saveData.tableStartTime) / setting.widthTime);
        var $bar = $('<div class="sc_bgBar"><span class="text"></span></div>');
        $bar.css({
          left: st * setting.widthTimeX,
          top: 0,
          width: (et - st) * setting.widthTimeX,
          height: $this.find('.sc_main .timeline').eq(data.timeline).height()
        });

        if (data.text) {
          $bar.find('.text').text(data.text);
        }

        if (data.class) {
          $bar.addClass(data.class);
        } // $element.find('.sc_main').append($bar);


        $this.find('.sc_main .timeline').eq(data.timeline).append($bar);
      });
    },

    /**
     * スケジュール追加
     *
     * @param timeline
     * @param {ScheduleData} d
     * @returns {number}
     */
    _addScheduleData: function _addScheduleData(timeline, d) {
      var data = d;
      data.startTime = data.startTime ? data.startTime : methods.calcStringTime(data.start);
      data.endTime = data.endTime ? data.endTime : methods.calcStringTime(data.end);
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var saveData = methods._loadData.apply($this);

        var st = Math.ceil((data.startTime - saveData.tableStartTime) / setting.widthTime);
        var et = Math.floor((data.endTime - saveData.tableStartTime) / setting.widthTime);
        var $bar = $('<div class="sc_bar"><span class="head"><span class="time"></span></span><span class="text"></span></div>');
        var stext = methods.formatTime(data.startTime);
        var etext = methods.formatTime(data.endTime);

        var snum = methods._getScheduleCount.apply($this, [data.timeline]);

        $bar.css({
          left: st * setting.widthTimeX,
          top: snum * setting.timeLineY + setting.timeLinePaddingTop,
          width: (et - st) * setting.widthTimeX,
          height: setting.timeLineY
        });
        $bar.find('.time').text(stext + '-' + etext);

        if (data.text) {
          $bar.find('.text').text(data.text);
        }

        if (data.class) {
          $bar.addClass(data.class);
        } // $this.find('.sc_main').append($bar);


        var $row = $this.find('.sc_main .timeline').eq(timeline);
        $row.append($bar); // データの追加

        saveData.schedule.push(data);

        methods._saveData.apply($this, [saveData]); // コールバックがセットされていたら呼出


        if (setting.onAppendSchedule) {
          setting.onAppendSchedule.apply($this, [$bar, data]);
        } // key


        var key = saveData.schedule.length - 1;
        $bar.data('sc_key', key);
        $bar.on('mouseup', function () {
          // コールバックがセットされていたら呼出
          if (setting.onClick) {
            if ($(this).data('dragCheck') !== true && $(this).data('resizeCheck') !== true) {
              var $n = $(this);
              var scKey = $n.data('sc_key');
              setting.onClick.apply($this, [$n, saveData.schedule[scKey]]);
            }
          }
        });
        var $node = $this.find('.sc_bar');
        var currentNode = null; // move node.

        $node.draggable({
          grid: [setting.widthTimeX, 1],
          containment: $this.find('.sc_main'),
          helper: 'original',
          start: function start(event, ui) {
            var node = {};
            node.node = this;
            node.offsetTop = ui.position.top;
            node.offsetLeft = ui.position.left;
            node.currentTop = ui.position.top;
            node.currentLeft = ui.position.left;
            node.timeline = methods._getTimeLineNumber.apply($this, [currentNode, ui.position.top]);
            node.nowTimeline = node.timeline;
            currentNode = node;
          },

          /**
           *
           * @param {Event} event
           * @param {function} ui
           * @returns {boolean}
           */
          drag: function drag(event, ui) {
            $(this).data('dragCheck', true);

            if (!currentNode) {
              return false;
            }

            var $moveNode = $(this);
            var scKey = $moveNode.data('sc_key');

            var timelineNum = methods._getTimeLineNumber.apply($this, [currentNode, ui.position.top]); // eslint-disable-next-line no-param-reassign


            ui.position.left = Math.floor(ui.position.left / setting.widthTimeX) * setting.widthTimeX;

            if (currentNode.nowTimeline !== timelineNum) {
              // 現在のタイムライン
              currentNode.nowTimeline = timelineNum;
            }

            currentNode.currentTop = ui.position.top;
            currentNode.currentLeft = ui.position.left; // テキスト変更

            methods._rewriteBarText.apply($this, [$moveNode, saveData.schedule[scKey]]);

            return true;
          },
          // 要素の移動が終った後の処理
          stop: function stop() {
            $(this).data('dragCheck', false);
            currentNode = null;
            var $n = $(this);
            var scKey = $n.data('sc_key');
            var x = $n.position().left; // var w = $n.width();

            var start = saveData.tableStartTime + Math.floor(x / setting.widthTimeX) * setting.widthTime; // var end = saveData.tableStartTime + (Math.floor((x + w) / setting.widthTimeX) * setting.widthTime);

            var end = start + (saveData.schedule[scKey].endTime - saveData.schedule[scKey].startTime);
            saveData.schedule[scKey].start = methods.formatTime(start);
            saveData.schedule[scKey].end = methods.formatTime(end);
            saveData.schedule[scKey].startTime = start;
            saveData.schedule[scKey].endTime = end; // コールバックがセットされていたら呼出

            if (setting.onChange) {
              setting.onChange.apply($this, [$n, saveData.schedule[scKey]]);
            }
          }
        });
        var resizableHandles = ['e'];

        if (setting.resizableLeft) {
          resizableHandles.push('w');
        }

        $node.resizable({
          handles: resizableHandles.join(','),
          grid: [setting.widthTimeX, setting.timeLineY - setting.timeBorder],
          minWidth: setting.widthTimeX,
          containment: $this.find('.sc_main_scroll'),
          start: function start() {
            var $n = $(this);
            $n.data('resizeCheck', true);
          },
          resize: function resize(ev, ui) {
            // box-sizing: border-box; に対応
            ui.element.height(ui.size.height);
            ui.element.width(ui.size.width);
          },
          // 要素の移動が終った後の処理
          stop: function stop() {
            var $n = $(this);
            var scKey = $n.data('sc_key');
            var x = $n.position().left;
            var w = $n.outerWidth();
            var start = saveData.tableStartTime + Math.floor(x / setting.widthTimeX) * setting.widthTime;
            var end = saveData.tableStartTime + Math.floor((x + w) / setting.widthTimeX) * setting.widthTime;
            var timelineNum = saveData.schedule[scKey].timeline;
            saveData.schedule[scKey].start = methods.formatTime(start);
            saveData.schedule[scKey].end = methods.formatTime(end);
            saveData.schedule[scKey].startTime = start;
            saveData.schedule[scKey].endTime = end; // 高さ調整

            methods._resetBarPosition.apply($this, [timelineNum]); // テキスト変更


            methods._rewriteBarText.apply($this, [$n, saveData.schedule[scKey]]);

            $n.data('resizeCheck', false); // コールバックがセットされていたら呼出

            if (setting.onChange) {
              setting.onChange.apply($this, [$n, saveData.schedule[scKey]]);
            }
          }
        });

        if (setting.draggable === false) {
          $node.draggable('disable');
        }

        if (setting.resizable === false) {
          $node.resizable('disable');
        }

        return key;
      });
    },

    /**
     * スケジュール数の取得
     *
     * @param {number} n row number
     * @returns {number}
     */
    _getScheduleCount: function _getScheduleCount(n) {
      var $this = $(this);

      var saveData = methods._loadData.apply($this);

      var num = 0;

      for (var i in saveData.schedule) {
        if (saveData.schedule[i].timeline === n) {
          num++;
        }
      }

      return num;
    },

    /**
     * add rows
     *
     * @param timeline
     * @param row
     */
    _addRow: function _addRow(timeline, row) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var saveData = methods._loadData.apply($this);

        var id = $this.find('.sc_main .timeline').length;
        var html;
        html = '';
        html += '<div class="timeline"></div>';
        var $data = $(html);

        if (row.title) {
          $data.append('<span class="timeline-title">' + row.title + '</span>');
        }

        if (row.subtitle) {
          $data.append('<span class="timeline-subtitle">' + row.subtitle + '</span>');
        } // event call


        if (setting.onInitRow) {
          setting.onInitRow.apply($this, [$data, row]);
        }

        $this.find('.sc_data_scroll').append($data);
        html = '';
        html += '<div class="timeline"></div>';
        var $timeline = $(html);

        for (var t = saveData.tableStartTime; t < saveData.tableEndTime; t += setting.widthTime) {
          var $tl = $('<div class="tl"></div>');
          $tl.outerWidth(setting.widthTimeX);
          $tl.data('time', methods.formatTime(t));
          $tl.data('timeline', timeline);
          $timeline.append($tl);
        } // クリックイベント
        // left click


        $timeline.find('.tl').on('click', function () {
          if (setting.onScheduleClick) {
            setting.onScheduleClick.apply($this, [this, $(this).data('time'), $(this).data('timeline'), saveData.timeline[$(this).data('timeline')]]);
          }
        }); // right click

        $timeline.find('.tl').on('contextmenu', function () {
          if (setting.onScheduleClick) {
            setting.onScheduleClick.apply($this, [this, $(this).data('time'), $(this).data('timeline'), saveData.timeline[$(this).data('timeline')]]);
          }

          return false;
        });
        $this.find('.sc_main').append($timeline);
        saveData.timeline[timeline] = row;

        methods._saveData.apply($this, [saveData]);

        if (row.class && row.class !== '') {
          $this.find('.sc_data .timeline').eq(id).addClass(row.class);
          $this.find('.sc_main .timeline').eq(id).addClass(row.class);
        } // スケジュールタイムライン


        if (row.schedule) {
          for (var i in row.schedule) {
            var bdata = row.schedule[i];
            var s = bdata.start ? bdata.start : methods.calcStringTime(bdata.startTime);
            var e = bdata.end ? bdata.end : methods.calcStringTime(bdata.endTime);
            var data = {};
            data.start = s;
            data.end = e;

            if (bdata.text) {
              data.text = bdata.text;
            }

            data.timeline = timeline;
            data.data = {};

            if (bdata.data) {
              data.data = bdata.data;
            }

            methods._addScheduleData.apply($this, [id, data]);
          }
        } // 高さの調整


        methods._resetBarPosition.apply($this, [id]);

        $this.find('.sc_main .timeline').eq(id).droppable({
          accept: '.sc_bar',
          drop: function drop(ev, ui) {
            var node = ui.draggable;
            var scKey = node.data('sc_key');
            var nowTimelineNum = saveData.schedule[scKey].timeline;
            var timelineNum = $this.find('.sc_main .timeline').index(this); // タイムラインの変更

            saveData.schedule[scKey].timeline = timelineNum;
            node.appendTo(this); // 高さ調整

            methods._resetBarPosition.apply($this, [nowTimelineNum]);

            methods._resetBarPosition.apply($this, [timelineNum]);
          }
        }); // コールバックがセットされていたら呼出

        if (setting.onAppendRow) {
          $this.find('.sc_main .timeline').eq(id).find('.sc_bar').each(function () {
            var $n = $(this);
            var scKey = $n.data('sc_key');
            setting.onAppendRow.apply($this, [$n, saveData.schedule[scKey]]);
          });
        }
      });
    },

    /**
     * テキストの変更
     *
     * @param {jQuery} node
     * @param {Object} data
     */
    _rewriteBarText: function _rewriteBarText(node, data) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var saveData = methods._loadData.apply($this);

        var x = node.position().left; // var w = node.width();

        var start = saveData.tableStartTime + Math.floor(x / setting.widthTimeX) * setting.widthTime; // var end = saveData.tableStartTime + (Math.floor((x + w) / setting.widthTimeX) * setting.widthTime);

        var end = start + (data.endTime - data.startTime);
        var html = methods.formatTime(start) + '-' + methods.formatTime(end);
        $(node).find('.time').html(html);
      });
    },

    /**
     *
     * @param {Number} n
     */
    _resetBarPosition: function _resetBarPosition(n) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this); // 要素の並び替え


        var $barList = $this.find('.sc_main .timeline').eq(n).find('.sc_bar');
        var codes = [],
            check = [];
        var h = 0;
        var $e1, $e2;
        var c1, c2, s1, s2, e1, e2;
        var i;

        for (i = 0; i < $barList.length; i++) {
          codes[i] = {
            code: i,
            x: $($barList[i]).position().left
          };
        } // ソート


        codes.sort(function (a, b) {
          if (a.x < b.x) {
            return -1;
          }

          if (a.x > b.x) {
            return 1;
          }

          return 0;
        });

        for (i = 0; i < codes.length; i++) {
          c1 = codes[i].code;
          $e1 = $($barList[c1]);

          for (h = 0; h < check.length; h++) {
            var next = false;

            for (var j = 0; j < check[h].length; j++) {
              c2 = check[h][j];
              $e2 = $($barList[c2]);
              s1 = $e1.position().left;
              e1 = $e1.position().left + $e1.outerWidth();
              s2 = $e2.position().left;
              e2 = $e2.position().left + $e2.outerWidth();

              if (s1 < e2 && e1 > s2) {
                next = true;
                continue;
              }
            }

            if (!next) {
              break;
            }
          }

          if (!check[h]) {
            check[h] = [];
          }

          $e1.css({
            top: h * setting.timeLineY + setting.timeLinePaddingTop
          });
          check[h][check[h].length] = c1;
        } // 高さの調整


        methods._resizeRow.apply($this, [n, check.length]);
      });
    },

    /**
     *
     * @param n
     * @param height
     */
    _resizeRow: function _resizeRow(n, height) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var h = Math.max(height, 1);
        $this.find('.sc_data .timeline').eq(n).outerHeight(h * setting.timeLineY + setting.timeLineBorder + setting.timeLinePaddingTop + setting.timeLinePaddingBottom);
        $this.find('.sc_main .timeline').eq(n).outerHeight(h * setting.timeLineY + setting.timeLineBorder + setting.timeLinePaddingTop + setting.timeLinePaddingBottom);
        $this.find('.sc_main .timeline').eq(n).find('.sc_bgBar').each(function () {
          $(this).outerHeight($(this).closest('.timeline').outerHeight());
        });
        $this.find('.sc_data').outerHeight($this.find('.sc_main_box').outerHeight());
      });
    },

    /**
     * resizeWindow
     */
    _resizeWindow: function _resizeWindow() {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var saveData = methods._loadData.apply($this);

        var scWidth = $this.width();
        var scMainWidth = scWidth - setting.dataWidth - setting.verticalScrollbar;
        var cellNum = Math.floor((saveData.tableEndTime - saveData.tableStartTime) / setting.widthTime);
        $this.find('.sc_header_cell').width(setting.dataWidth);
        $this.find('.sc_data,.sc_data_scroll').width(setting.dataWidth);
        $this.find('.sc_header').width(scMainWidth);
        $this.find('.sc_main_box').width(scMainWidth);
        $this.find('.sc_header_scroll').width(setting.widthTimeX * cellNum);
        $this.find('.sc_main_scroll').width(setting.widthTimeX * cellNum);
      });
    },

    /**
     * move all cells of the right of the specified time line cell
     *
     * @param timeline
     * @param baseTimeLineCell
     * @param moveWidth
     */
    _moveSchedules: function _moveSchedules(timeline, baseTimeLineCell, moveWidth) {
      return this.each(function () {
        var $this = $(this);

        var setting = methods._loadSettingData.apply($this);

        var saveData = methods._loadData.apply($this);

        var $barList = $this.find('.sc_main .timeline').eq(timeline).find('.sc_bar');

        for (var i = 0; i < $barList.length; i++) {
          var $bar = $($barList[i]);

          if (baseTimeLineCell.position().left <= $bar.position().left) {
            var v1 = $bar.position().left + setting.widthTimeX * moveWidth;
            var v2 = Math.floor((saveData.tableEndTime - saveData.tableStartTime) / setting.widthTime) * setting.widthTimeX - $bar.outerWidth();
            $bar.css({
              left: Math.max(0, Math.min(v1, v2))
            });
            var scKey = $bar.data('sc_key');
            var start = saveData.tableStartTime + Math.floor($bar.position().left / setting.widthTimeX) * setting.widthTime;
            var end = start + (saveData.schedule[scKey].end - saveData.schedule[scKey].start);
            saveData.schedule[scKey].start = methods.formatTime(start);
            saveData.schedule[scKey].end = methods.formatTime(end);
            saveData.schedule[scKey].startTime = start;
            saveData.schedule[scKey].endTime = end;

            methods._rewriteBarText.apply($this, [$bar, saveData.schedule[scKey]]); // if setting


            if (setting.onChange) {
              setting.onChange.apply($this, [$bar, saveData.schedule[scKey]]);
            }
          }
        }

        methods._resetBarPosition.apply($this, [timeline]);
      });
    },

    /**
     * initialize
     */
    init: function init(options) {
      return this.each(function () {
        var $this = $(this);
        var config = $.extend({
          className: 'jq-schedule',
          rows: {},
          startTime: '07:00',
          endTime: '19:30',
          widthTimeX: 25,
          // 1cell辺りの幅(px)
          widthTime: 600,
          // 区切り時間(秒)
          timeLineY: 50,
          // timeline height(px)
          timeLineBorder: 1,
          // timeline height border
          timeBorder: 1,
          // border width
          timeLinePaddingTop: 0,
          timeLinePaddingBottom: 0,
          headTimeBorder: 1,
          // time border width
          dataWidth: 160,
          // data width
          verticalScrollbar: 0,
          // vertical scrollbar width
          bundleMoveWidth: 1,
          // width to move all schedules to the right of the clicked time cell
          draggable: true,
          resizable: true,
          resizableLeft: false,
          // event
          onInitRow: null,
          onChange: null,
          onClick: null,
          onAppendRow: null,
          onAppendSchedule: null,
          onScheduleClick: null
        }, options);

        methods._saveSettingData.apply($this, [config]);

        var tableStartTime = methods.calcStringTime(config.startTime);
        var tableEndTime = methods.calcStringTime(config.endTime);
        tableStartTime -= tableStartTime % config.widthTime;
        tableEndTime -= tableEndTime % config.widthTime;

        methods._saveData.apply($this, [{
          tableStartTime: tableStartTime,
          tableEndTime: tableEndTime
        }]);

        var html = '' + '<div class="sc_menu">' + '\n' + '<div class="sc_header_cell"><span>&nbsp;</span></div>' + '\n' + '<div class="sc_header">' + '\n' + '<div class="sc_header_scroll"></div>' + '\n' + '</div>' + '\n' + '</div>' + '\n' + '<div class="sc_wrapper">' + '\n' + '<div class="sc_data">' + '\n' + '<div class="sc_data_scroll"></div>' + '\n' + '</div>' + '\n' + '<div class="sc_main_box">' + '\n' + '<div class="sc_main_scroll">' + '\n' + '<div class="sc_main"></div>' + '\n' + '</div>' + '\n' + '</div>' + '\n' + '</div>';
        $this.append(html);
        $this.addClass(config.className);
        $this.find('.sc_main_box').on('scroll', function () {
          $this.find('.sc_data_scroll').css('top', $(this).scrollTop() * -1);
          $this.find('.sc_header_scroll').css('left', $(this).scrollLeft() * -1);
        }); // add time cell
        // var cellNum = Math.floor((tableEndTime - tableStartTime) / config.widthTime);

        var beforeTime = -1;

        for (var t = tableStartTime; t < tableEndTime; t += config.widthTime) {
          if (beforeTime < 0 || Math.floor(beforeTime / 3600) !== Math.floor(t / 3600)) {
            html = '';
            html += '<div class="sc_time">' + methods.formatTime(t) + '</div>';
            var $time = $(html);
            var cn = Number(Math.min(Math.ceil((t + config.widthTime) / 3600) * 3600, tableEndTime) - t);
            var cellNum = Math.floor(cn / config.widthTime);
            $time.width(cellNum * config.widthTimeX);
            $this.find('.sc_header_scroll').append($time);
            beforeTime = t;
          }
        }

        $(window).on('resize', function () {
          methods._resizeWindow.apply($this);
        }).trigger('resize'); // addrow

        for (var i in config.rows) {
          methods._addRow.apply($this, [i, config.rows[i]]);
        }
      });
    }
  };
  /**
   *
   * @param {Object|string} method
   * @returns {jQuery|methods|*}
   */
  // eslint-disable-next-line no-param-reassign

  $.fn.timeSchedule = function (method) {
    // Method calling logic
    if (methods[method]) {
      return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); // eslint-disable-next-line no-else-return
    } else if (_typeof(method) === 'object' || !method) {
      return methods.init.apply(this, arguments);
    }

    $.error('Method ' + method + ' does not exist on jQuery.timeSchedule');
    return this;
  };
})(jQuery);