{"action":"created","comment":{"url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls/comments/200810817","pull_request_review_id":135202706,"id":200810817,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwMDgxMDgxNw==","diff_hunk":"@@ -1,571 +1,615 @@\n-import React, { Component } from 'react'\n-import PropTypes from 'prop-types'\n-import interact from 'interactjs'\n-import moment from 'moment'\n-\n-import { _get, deepObjectCompare } from '../utility/generic'\n-\n-export default class Item extends Component {\n-  // removed prop type check for SPEED!\n-  // they are coming from a trusted component anyway\n-  // (this complicates performance debugging otherwise)\n-  static propTypes = {\n-    canvasTimeStart: PropTypes.number.isRequired,\n-    canvasTimeEnd: PropTypes.number.isRequired,\n-    canvasWidth: PropTypes.number.isRequired,\n-    order: PropTypes.number,\n-    minimumWidthForItemContentVisibility: PropTypes.number.isRequired,\n-\n-    dragSnap: PropTypes.number,\n-    minResizeWidth: PropTypes.number,\n-    selected: PropTypes.bool,\n-\n-    canChangeGroup: PropTypes.bool.isRequired,\n-    canMove: PropTypes.bool.isRequired,\n-    canResizeLeft: PropTypes.bool.isRequired,\n-    canResizeRight: PropTypes.bool.isRequired,\n-\n-    keys: PropTypes.object.isRequired,\n-    item: PropTypes.object.isRequired,\n-\n-    onSelect: PropTypes.func,\n-    onDrag: PropTypes.func,\n-    onDrop: PropTypes.func,\n-    onResizing: PropTypes.func,\n-    onResized: PropTypes.func,\n-    onContextMenu: PropTypes.func,\n-    itemRenderer: PropTypes.func,\n-\n-    itemProps: PropTypes.object,\n-    canSelect: PropTypes.bool,\n-    topOffset: PropTypes.number,\n-    dimensions: PropTypes.object,\n-    groupTops: PropTypes.array,\n-    useResizeHandle: PropTypes.bool,\n-    moveResizeValidator: PropTypes.func,\n-    onItemDoubleClick: PropTypes.func\n-  }\n-\n-  static defaultProps = {\n-    selected: false\n-  }\n-\n-  static contextTypes = {\n-    getTimelineContext: PropTypes.func\n-  }\n-\n-  constructor(props) {\n-    super(props)\n-\n-    this.cacheDataFromProps(props)\n-\n-    this.state = {\n-      interactMounted: false,\n-\n-      dragging: null,\n-      dragStart: null,\n-      preDragPosition: null,\n-      dragTime: null,\n-      dragGroupDelta: null,\n-\n-      resizing: null,\n-      resizeEdge: null,\n-      resizeStart: null,\n-      resizeTime: null\n-    }\n-  }\n-\n-  shouldComponentUpdate(nextProps, nextState) {\n-    var shouldUpdate =\n-      nextState.dragging !== this.state.dragging ||\n-      nextState.dragTime !== this.state.dragTime ||\n-      nextState.dragGroupDelta !== this.state.dragGroupDelta ||\n-      nextState.resizing !== this.state.resizing ||\n-      nextState.resizeTime !== this.state.resizeTime ||\n-      nextProps.keys !== this.props.keys ||\n-      !deepObjectCompare(nextProps.itemProps, this.props.itemProps) ||\n-      nextProps.selected !== this.props.selected ||\n-      nextProps.item !== this.props.item ||\n-      nextProps.canvasTimeStart !== this.props.canvasTimeStart ||\n-      nextProps.canvasTimeEnd !== this.props.canvasTimeEnd ||\n-      nextProps.canvasWidth !== this.props.canvasWidth ||\n-      nextProps.order !== this.props.order ||\n-      nextProps.dragSnap !== this.props.dragSnap ||\n-      nextProps.minResizeWidth !== this.props.minResizeWidth ||\n-      nextProps.canChangeGroup !== this.props.canChangeGroup ||\n-      nextProps.canSelect !== this.props.canSelect ||\n-      nextProps.topOffset !== this.props.topOffset ||\n-      nextProps.canMove !== this.props.canMove ||\n-      nextProps.canResizeLeft !== this.props.canResizeLeft ||\n-      nextProps.canResizeRight !== this.props.canResizeRight ||\n-      nextProps.dimensions !== this.props.dimensions ||\n-      nextProps.minimumWidthForItemContentVisibility !==\n-        this.props.minimumWidthForItemContentVisibility\n-    return shouldUpdate\n-  }\n-\n-  cacheDataFromProps(props) {\n-    this.itemId = _get(props.item, props.keys.itemIdKey)\n-    this.itemTitle = _get(props.item, props.keys.itemTitleKey)\n-    this.itemDivTitle = props.keys.itemDivTitleKey\n-      ? _get(props.item, props.keys.itemDivTitleKey)\n-      : this.itemTitle\n-    this.itemTimeStart = _get(props.item, props.keys.itemTimeStartKey)\n-    this.itemTimeEnd = _get(props.item, props.keys.itemTimeEndKey)\n-  }\n-\n-  // TODO: this is same as coordinateToTimeRatio in utilities\n-  coordinateToTimeRatio(props = this.props) {\n-    return (props.canvasTimeEnd - props.canvasTimeStart) / props.canvasWidth\n-  }\n-\n-  dragTimeSnap(dragTime, considerOffset) {\n-    const { dragSnap } = this.props\n-    if (dragSnap) {\n-      const offset = considerOffset ? moment().utcOffset() * 60 * 1000 : 0\n-      return Math.round(dragTime / dragSnap) * dragSnap - offset % dragSnap\n-    } else {\n-      return dragTime\n-    }\n-  }\n-\n-  resizeTimeSnap(dragTime) {\n-    const { dragSnap } = this.props\n-    if (dragSnap) {\n-      const endTime = this.itemTimeEnd % dragSnap\n-      return Math.round((dragTime - endTime) / dragSnap) * dragSnap + endTime\n-    } else {\n-      return dragTime\n-    }\n-  }\n-\n-  dragTime(e) {\n-    const startTime = moment(this.itemTimeStart)\n-\n-    if (this.state.dragging) {\n-      const deltaX = e.pageX - this.state.dragStart.x\n-      const timeDelta = deltaX * this.coordinateToTimeRatio()\n-\n-      return this.dragTimeSnap(startTime.valueOf() + timeDelta, true)\n-    } else {\n-      return startTime\n-    }\n-  }\n-\n-  dragGroupDelta(e) {\n-    const { groupTops, order, topOffset } = this.props\n-    if (this.state.dragging) {\n-      if (!this.props.canChangeGroup) {\n-        return 0\n-      }\n-      let groupDelta = 0\n-\n-      for (var key of Object.keys(groupTops)) {\n-        var item = groupTops[key]\n-        if (e.pageY - topOffset > item) {\n-          groupDelta = parseInt(key, 10) - order\n-        } else {\n-          break\n-        }\n-      }\n-\n-      if (this.props.order + groupDelta < 0) {\n-        return 0 - this.props.order\n-      } else {\n-        return groupDelta\n-      }\n-    } else {\n-      return 0\n-    }\n-  }\n-\n-  resizeTimeDelta(e, resizeEdge) {\n-    const length = this.itemTimeEnd - this.itemTimeStart\n-    const timeDelta = this.dragTimeSnap(\n-      (e.pageX - this.state.resizeStart) * this.coordinateToTimeRatio()\n-    )\n-\n-    if (\n-      length + (resizeEdge === 'left' ? -timeDelta : timeDelta) <\n-      (this.props.dragSnap || 1000)\n-    ) {\n-      if (resizeEdge === 'left') {\n-        return length - (this.props.dragSnap || 1000)\n-      } else {\n-        return (this.props.dragSnap || 1000) - length\n-      }\n-    } else {\n-      return timeDelta\n-    }\n-  }\n-\n-  mountInteract() {\n-    const leftResize = this.props.useResizeHandle ? this.dragLeft : true\n-    const rightResize = this.props.useResizeHandle ? this.dragRight : true\n-\n-    interact(this.item)\n-      .resizable({\n-        edges: {\n-          left: this.canResizeLeft() && leftResize,\n-          right: this.canResizeRight() && rightResize,\n-          top: false,\n-          bottom: false\n-        },\n-        enabled:\n-          this.props.selected && (this.canResizeLeft() || this.canResizeRight())\n-      })\n-      .draggable({\n-        enabled: this.props.selected\n-      })\n-      .styleCursor(false)\n-      .on('dragstart', e => {\n-        if (this.props.selected) {\n-          this.setState({\n-            dragging: true,\n-            dragStart: { x: e.pageX, y: e.pageY },\n-            preDragPosition: { x: e.target.offsetLeft, y: e.target.offsetTop },\n-            dragTime: this.itemTimeStart,\n-            dragGroupDelta: 0\n-          })\n-        } else {\n-          return false\n-        }\n-      })\n-      .on('dragmove', e => {\n-        if (this.state.dragging) {\n-          let dragTime = this.dragTime(e)\n-          let dragGroupDelta = this.dragGroupDelta(e)\n-\n-          if (this.props.moveResizeValidator) {\n-            dragTime = this.props.moveResizeValidator(\n-              'move',\n-              this.props.item,\n-              dragTime\n-            )\n-          }\n-\n-          if (this.props.onDrag) {\n-            this.props.onDrag(\n-              this.itemId,\n-              dragTime,\n-              this.props.order + dragGroupDelta\n-            )\n-          }\n-\n-          this.setState({\n-            dragTime: dragTime,\n-            dragGroupDelta: dragGroupDelta\n-          })\n-        }\n-      })\n-      .on('dragend', e => {\n-        if (this.state.dragging) {\n-          if (this.props.onDrop) {\n-            let dragTime = this.dragTime(e)\n-\n-            if (this.props.moveResizeValidator) {\n-              dragTime = this.props.moveResizeValidator(\n-                'move',\n-                this.props.item,\n-                dragTime\n-              )\n-            }\n-\n-            this.props.onDrop(\n-              this.itemId,\n-              dragTime,\n-              this.props.order + this.dragGroupDelta(e)\n-            )\n-          }\n-\n-          this.setState({\n-            dragging: false,\n-            dragStart: null,\n-            preDragPosition: null,\n-            dragTime: null,\n-            dragGroupDelta: null\n-          })\n-        }\n-      })\n-      .on('resizestart', e => {\n-        if (this.props.selected) {\n-          this.setState({\n-            resizing: true,\n-            resizeEdge: null, // we don't know yet\n-            resizeStart: e.pageX,\n-            resizeTime: 0\n-          })\n-        } else {\n-          return false\n-        }\n-      })\n-      .on('resizemove', e => {\n-        if (this.state.resizing) {\n-          let resizeEdge = this.state.resizeEdge\n-\n-          if (!resizeEdge) {\n-            resizeEdge = e.deltaRect.left !== 0 ? 'left' : 'right'\n-            this.setState({ resizeEdge })\n-          }\n-          const time =\n-            resizeEdge === 'left' ? this.itemTimeStart : this.itemTimeEnd\n-\n-          let resizeTime = this.resizeTimeSnap(\n-            time + this.resizeTimeDelta(e, resizeEdge)\n-          )\n-\n-          if (this.props.moveResizeValidator) {\n-            resizeTime = this.props.moveResizeValidator(\n-              'resize',\n-              this.props.item,\n-              resizeTime,\n-              resizeEdge\n-            )\n-          }\n-\n-          if (this.props.onResizing) {\n-            this.props.onResizing(this.itemId, resizeTime, resizeEdge)\n-          }\n-\n-          this.setState({\n-            resizeTime\n-          })\n-        }\n-      })\n-      .on('resizeend', e => {\n-        if (this.state.resizing) {\n-          const { resizeEdge } = this.state\n-          const time =\n-            resizeEdge === 'left' ? this.itemTimeStart : this.itemTimeEnd\n-          let resizeTime = this.resizeTimeSnap(\n-            time + this.resizeTimeDelta(e, resizeEdge)\n-          )\n-\n-          if (this.props.moveResizeValidator) {\n-            resizeTime = this.props.moveResizeValidator(\n-              'resize',\n-              this.props.item,\n-              resizeTime,\n-              resizeEdge\n-            )\n-          }\n-\n-          if (this.props.onResized) {\n-            this.props.onResized(\n-              this.itemId,\n-              resizeTime,\n-              resizeEdge,\n-              this.resizeTimeDelta(e, resizeEdge)\n-            )\n-          }\n-          this.setState({\n-            resizing: null,\n-            resizeStart: null,\n-            resizeEdge: null,\n-            resizeTime: null\n-          })\n-        }\n-      })\n-      .on('tap', e => {\n-        this.actualClick(e, e.pointerType === 'mouse' ? 'click' : 'touch')\n-      })\n-\n-    this.setState({\n-      interactMounted: true\n-    })\n-  }\n-\n-  canResizeLeft(props = this.props) {\n-    if (!props.canResizeLeft) {\n-      return false\n-    }\n-    let width = parseInt(props.dimensions.width, 10)\n-    return width >= props.minResizeWidth\n-  }\n-\n-  canResizeRight(props = this.props) {\n-    if (!props.canResizeRight) {\n-      return false\n-    }\n-    let width = parseInt(props.dimensions.width, 10)\n-    return width >= props.minResizeWidth\n-  }\n-\n-  canMove(props = this.props) {\n-    return !!props.canMove\n-  }\n-\n-  componentWillReceiveProps(nextProps) {\n-    this.cacheDataFromProps(nextProps)\n-\n-    let { interactMounted } = this.state\n-    const couldDrag = this.props.selected && this.canMove(this.props)\n-    const couldResizeLeft =\n-      this.props.selected && this.canResizeLeft(this.props)\n-    const couldResizeRight =\n-      this.props.selected && this.canResizeRight(this.props)\n-    const willBeAbleToDrag = nextProps.selected && this.canMove(nextProps)\n-    const willBeAbleToResizeLeft =\n-      nextProps.selected && this.canResizeLeft(nextProps)\n-    const willBeAbleToResizeRight =\n-      nextProps.selected && this.canResizeRight(nextProps)\n-\n-    if (nextProps.selected && !interactMounted) {\n-      this.mountInteract()\n-      interactMounted = true\n-    }\n-\n-    if (\n-      interactMounted &&\n-      (couldResizeLeft !== willBeAbleToResizeLeft ||\n-        couldResizeRight !== willBeAbleToResizeRight)\n-    ) {\n-      const leftResize = this.props.useResizeHandle ? this.dragLeft : true\n-      const rightResize = this.props.useResizeHandle ? this.dragRight : true\n-\n-      interact(this.item).resizable({\n-        enabled: willBeAbleToResizeLeft || willBeAbleToResizeRight,\n-        edges: {\n-          top: false,\n-          bottom: false,\n-          left: willBeAbleToResizeLeft && leftResize,\n-          right: willBeAbleToResizeRight && rightResize\n-        }\n-      })\n-    }\n-    if (interactMounted && couldDrag !== willBeAbleToDrag) {\n-      interact(this.item).draggable({ enabled: willBeAbleToDrag })\n-    }\n-  }\n-\n-  onMouseDown = e => {\n-    if (!this.state.interactMounted) {\n-      e.preventDefault()\n-      this.startedClicking = true\n-    }\n-  }\n-\n-  onMouseUp = e => {\n-    if (!this.state.interactMounted && this.startedClicking) {\n-      this.startedClicking = false\n-      this.actualClick(e, 'click')\n-    }\n-  }\n-\n-  onTouchStart = e => {\n-    if (!this.state.interactMounted) {\n-      e.preventDefault()\n-      this.startedTouching = true\n-    }\n-  }\n-\n-  onTouchEnd = e => {\n-    if (!this.state.interactMounted && this.startedTouching) {\n-      this.startedTouching = false\n-      this.actualClick(e, 'touch')\n-    }\n-  }\n-\n-  handleDoubleClick = e => {\n-    e.stopPropagation()\n-    if (this.props.onItemDoubleClick) {\n-      this.props.onItemDoubleClick(this.itemId, e)\n-    }\n-  }\n-\n-  handleContextMenu = e => {\n-    if (this.props.onContextMenu) {\n-      e.preventDefault()\n-      e.stopPropagation()\n-      this.props.onContextMenu(this.itemId, e)\n-    }\n-  }\n-\n-  actualClick(e, clickType) {\n-    if (this.props.canSelect && this.props.onSelect) {\n-      this.props.onSelect(this.itemId, clickType, e)\n-    }\n-  }\n-\n-  renderContent() {\n-    const timelineContext = this.context.getTimelineContext()\n-    const Comp = this.props.itemRenderer\n-    if (Comp) {\n-      return <Comp item={this.props.item} timelineContext={timelineContext} />\n-    } else {\n-      return this.itemTitle\n-    }\n-  }\n-\n-  render() {\n-    const dimensions = this.props.dimensions\n-    if (typeof this.props.order === 'undefined' || this.props.order === null) {\n-      return null\n-    }\n-\n-    const classNames =\n-      'rct-item' +\n-      (this.props.selected ? ' selected' : '') +\n-      (this.canMove(this.props) ? ' can-move' : '') +\n-      (this.canResizeLeft(this.props) || this.canResizeRight(this.props)\n-        ? ' can-resize'\n-        : '') +\n-      (this.canResizeLeft(this.props) ? ' can-resize-left' : '') +\n-      (this.canResizeRight(this.props) ? ' can-resize-right' : '') +\n-      (this.props.item.className ? ` ${this.props.item.className}` : '')\n-\n-    const style = {\n-      left: `${dimensions.left}px`,\n-      top: `${dimensions.top}px`,\n-      width: `${dimensions.width}px`,\n-      height: `${dimensions.height}px`,\n-      lineHeight: `${dimensions.height}px`\n-    }\n-\n-    const showInnerContents =\n-      dimensions.width > this.props.minimumWidthForItemContentVisibility\n-    // TODO: conditionals are really ugly.  could use Fragment if supporting React 16+ but for now, it'll\n-    // be ugly\n-    return (\n-      <div\n-        {...this.props.item.itemProps}\n-        key={this.itemId}\n-        ref={el => (this.item = el)}\n-        className={classNames}\n-        title={this.itemDivTitle}\n-        onMouseDown={this.onMouseDown}\n-        onMouseUp={this.onMouseUp}\n-        onTouchStart={this.onTouchStart}\n-        onTouchEnd={this.onTouchEnd}\n-        onDoubleClick={this.handleDoubleClick}\n-        onContextMenu={this.handleContextMenu}\n-        style={style}\n-      >\n-        {this.props.useResizeHandle && showInnerContents ? (\n-          <div ref={el => (this.dragLeft = el)} className=\"rct-drag-left\" />\n-        ) : (\n-          ''\n-        )}\n-\n-        {showInnerContents ? (\n-          <div\n-            className=\"rct-item-content\"\n-            style={{\n-              maxWidth: `${dimensions.width}px`\n-            }}\n-          >\n-            {this.renderContent()}\n-          </div>\n-        ) : (\n-          ''\n-        )}\n-\n-        {this.props.useResizeHandle && showInnerContents ? (\n-          <div ref={el => (this.dragRight = el)} className=\"rct-drag-right\" />\n-        ) : (\n-          ''\n-        )}\n-      </div>\n-    )\n-  }\n-}\n+import React, { Component } from 'react'\r\n+import PropTypes from 'prop-types'\r\n+import interact from 'interactjs'\r\n+import moment from 'moment'\r\n+\r\n+import { _get, deepObjectCompare } from '../utility/generic'\r\n+import { composeEvents } from '../utility/events'\r\n+\r\n+export default class Item extends Component {\r\n+  // removed prop type check for SPEED!\r\n+  // they are coming from a trusted component anyway\r\n+  // (this complicates performance debugging otherwise)\r\n+  static propTypes = {\r\n+    canvasTimeStart: PropTypes.number.isRequired,\r\n+    canvasTimeEnd: PropTypes.number.isRequired,\r\n+    canvasWidth: PropTypes.number.isRequired,\r\n+    order: PropTypes.number,\r\n+    minimumWidthForItemContentVisibility: PropTypes.number.isRequired,\r\n+\r\n+    dragSnap: PropTypes.number,\r\n+    minResizeWidth: PropTypes.number,\r\n+    selected: PropTypes.bool,\r\n+\r\n+    canChangeGroup: PropTypes.bool.isRequired,\r\n+    canMove: PropTypes.bool.isRequired,\r\n+    canResizeLeft: PropTypes.bool.isRequired,\r\n+    canResizeRight: PropTypes.bool.isRequired,\r\n+\r\n+    keys: PropTypes.object.isRequired,\r\n+    item: PropTypes.object.isRequired,\r\n+\r\n+    onSelect: PropTypes.func,\r\n+    onDrag: PropTypes.func,\r\n+    onDrop: PropTypes.func,\r\n+    onResizing: PropTypes.func,\r\n+    onResized: PropTypes.func,\r\n+    onContextMenu: PropTypes.func,\r\n+    itemRenderer: PropTypes.func,\r\n+\r\n+    itemProps: PropTypes.object,\r\n+    canSelect: PropTypes.bool,\r\n+    topOffset: PropTypes.number,\r\n+    dimensions: PropTypes.object,\r\n+    groupTops: PropTypes.array,\r\n+    useResizeHandle: PropTypes.bool,\r\n+    moveResizeValidator: PropTypes.func,\r\n+    onItemDoubleClick: PropTypes.func\r\n+  }\r\n+\r\n+  static defaultProps = {\r\n+    selected: false,\r\n+    itemRenderer: ({\r\n+      item,\r\n+      timelineContext,\r\n+      itemContext,\r\n+      getItemProps,\r\n+      getResizeProps,\r\n+    }) => {\r\n+      const { left: leftResizeProps, right: rightResizeProps } = getResizeProps()\r\n+      return (\r\n+        <div\r\n+          {...getItemProps(item.itemProps) }\r\n+        >\r\n+          {itemContext.useResizeHandle && itemContext.showInnerContentsRender ? (\r\n+            <div {...leftResizeProps} />\r\n+          ) : (\r\n+              ''\r\n+            )}\r\n+\r\n+          {itemContext.showInnerContentsRender && <div\r\n+            className=\"rct-item-content\"\r\n+            style={{maxHeight: `${itemContext.dimensions.height}`}}\r\n+          >\r\n+            {itemContext.title}\r\n+          </div>}\r\n+\r\n+\r\n+          {itemContext.useResizeHandle && itemContext.showInnerContentsRender ? (\r\n+            <div {...rightResizeProps} />\r\n+          ) : (\r\n+              ''\r\n+            )}\r\n+        </div>\r\n+      )\r\n+    }\r\n+  }\r\n+\r\n+  static contextTypes = {\r\n+    getTimelineContext: PropTypes.func\r\n+  }\r\n+\r\n+  constructor(props) {\r\n+    super(props)\r\n+\r\n+    this.cacheDataFromProps(props)\r\n+\r\n+    this.state = {\r\n+      interactMounted: false,\r\n+\r\n+      dragging: null,\r\n+      dragStart: null,\r\n+      preDragPosition: null,\r\n+      dragTime: null,\r\n+      dragGroupDelta: null,\r\n+\r\n+      resizing: null,\r\n+      resizeEdge: null,\r\n+      resizeStart: null,\r\n+      resizeTime: null\r\n+    }\r\n+  }\r\n+\r\n+  shouldComponentUpdate(nextProps, nextState) {\r\n+    var shouldUpdate =\r\n+      nextState.dragging !== this.state.dragging ||\r\n+      nextState.dragTime !== this.state.dragTime ||\r\n+      nextState.dragGroupDelta !== this.state.dragGroupDelta ||\r\n+      nextState.resizing !== this.state.resizing ||\r\n+      nextState.resizeTime !== this.state.resizeTime ||\r\n+      nextProps.keys !== this.props.keys ||\r\n+      !deepObjectCompare(nextProps.itemProps, this.props.itemProps) ||\r\n+      nextProps.selected !== this.props.selected ||\r\n+      nextProps.item !== this.props.item ||\r\n+      nextProps.canvasTimeStart !== this.props.canvasTimeStart ||\r\n+      nextProps.canvasTimeEnd !== this.props.canvasTimeEnd ||\r\n+      nextProps.canvasWidth !== this.props.canvasWidth ||\r\n+      nextProps.order !== this.props.order ||\r\n+      nextProps.dragSnap !== this.props.dragSnap ||\r\n+      nextProps.minResizeWidth !== this.props.minResizeWidth ||\r\n+      nextProps.canChangeGroup !== this.props.canChangeGroup ||\r\n+      nextProps.canSelect !== this.props.canSelect ||\r\n+      nextProps.topOffset !== this.props.topOffset ||\r\n+      nextProps.canMove !== this.props.canMove ||\r\n+      nextProps.canResizeLeft !== this.props.canResizeLeft ||\r\n+      nextProps.canResizeRight !== this.props.canResizeRight ||\r\n+      nextProps.dimensions !== this.props.dimensions ||\r\n+      nextProps.minimumWidthForItemContentVisibility !==\r\n+      this.props.minimumWidthForItemContentVisibility\r\n+    return shouldUpdate\r\n+  }\r\n+\r\n+  cacheDataFromProps(props) {\r\n+    this.itemId = _get(props.item, props.keys.itemIdKey)\r\n+    this.itemTitle = _get(props.item, props.keys.itemTitleKey)\r\n+    this.itemDivTitle = props.keys.itemDivTitleKey\r\n+      ? _get(props.item, props.keys.itemDivTitleKey)\r\n+      : this.itemTitle\r\n+    this.itemTimeStart = _get(props.item, props.keys.itemTimeStartKey)\r\n+    this.itemTimeEnd = _get(props.item, props.keys.itemTimeEndKey)\r\n+  }\r\n+\r\n+  // TODO: this is same as coordinateToTimeRatio in utilities\r\n+  coordinateToTimeRatio(props = this.props) {\r\n+    return (props.canvasTimeEnd - props.canvasTimeStart) / props.canvasWidth\r\n+  }\r\n+\r\n+  dragTimeSnap(dragTime, considerOffset) {\r\n+    const { dragSnap } = this.props\r\n+    if (dragSnap) {\r\n+      const offset = considerOffset ? moment().utcOffset() * 60 * 1000 : 0\r\n+      return Math.round(dragTime / dragSnap) * dragSnap - offset % dragSnap\r\n+    } else {\r\n+      return dragTime\r\n+    }\r\n+  }\r\n+\r\n+  resizeTimeSnap(dragTime) {\r\n+    const { dragSnap } = this.props\r\n+    if (dragSnap) {\r\n+      const endTime = this.itemTimeEnd % dragSnap\r\n+      return Math.round((dragTime - endTime) / dragSnap) * dragSnap + endTime\r\n+    } else {\r\n+      return dragTime\r\n+    }\r\n+  }\r\n+\r\n+  dragTime(e) {\r\n+    const startTime = moment(this.itemTimeStart)\r\n+\r\n+    if (this.state.dragging) {\r\n+      const deltaX = e.pageX - this.state.dragStart.x\r\n+      const timeDelta = deltaX * this.coordinateToTimeRatio()\r\n+\r\n+      return this.dragTimeSnap(startTime.valueOf() + timeDelta, true)\r\n+    } else {\r\n+      return startTime\r\n+    }\r\n+  }\r\n+\r\n+  dragGroupDelta(e) {\r\n+    const { groupTops, order, topOffset } = this.props\r\n+    if (this.state.dragging) {\r\n+      if (!this.props.canChangeGroup) {\r\n+        return 0\r\n+      }\r\n+      let groupDelta = 0\r\n+\r\n+      for (var key of Object.keys(groupTops)) {\r\n+        var item = groupTops[key]\r\n+        if (e.pageY - topOffset > item) {\r\n+          groupDelta = parseInt(key, 10) - order\r\n+        } else {\r\n+          break\r\n+        }\r\n+      }\r\n+\r\n+      if (this.props.order + groupDelta < 0) {\r\n+        return 0 - this.props.order\r\n+      } else {\r\n+        return groupDelta\r\n+      }\r\n+    } else {\r\n+      return 0\r\n+    }\r\n+  }\r\n+\r\n+  resizeTimeDelta(e, resizeEdge) {\r\n+    const length = this.itemTimeEnd - this.itemTimeStart\r\n+    const timeDelta = this.dragTimeSnap(\r\n+      (e.pageX - this.state.resizeStart) * this.coordinateToTimeRatio()\r\n+    )\r\n+\r\n+    if (\r\n+      length + (resizeEdge === 'left' ? -timeDelta : timeDelta) <\r\n+      (this.props.dragSnap || 1000)\r\n+    ) {\r\n+      if (resizeEdge === 'left') {\r\n+        return length - (this.props.dragSnap || 1000)\r\n+      } else {\r\n+        return (this.props.dragSnap || 1000) - length\r\n+      }\r\n+    } else {\r\n+      return timeDelta\r\n+    }\r\n+  }\r\n+\r\n+  mountInteract() {\r\n+    const leftResize = this.props.useResizeHandle ? this.dragLeft : true\r\n+    const rightResize = this.props.useResizeHandle ? this.dragRight : true\r\n+\r\n+    interact(this.item)\r\n+      .resizable({\r\n+        edges: {\r\n+          left: this.canResizeLeft() && leftResize,\r\n+          right: this.canResizeRight() && rightResize,\r\n+          top: false,\r\n+          bottom: false\r\n+        },\r\n+        enabled:\r\n+          this.props.selected && (this.canResizeLeft() || this.canResizeRight())\r\n+      })\r\n+      .draggable({\r\n+        enabled: this.props.selected\r\n+      })\r\n+      .styleCursor(false)\r\n+      .on('dragstart', e => {\r\n+        if (this.props.selected) {\r\n+          this.setState({\r\n+            dragging: true,\r\n+            dragStart: { x: e.pageX, y: e.pageY },\r\n+            preDragPosition: { x: e.target.offsetLeft, y: e.target.offsetTop },\r\n+            dragTime: this.itemTimeStart,\r\n+            dragGroupDelta: 0\r\n+          })\r\n+        } else {\r\n+          return false\r\n+        }\r\n+      })\r\n+      .on('dragmove', e => {\r\n+        if (this.state.dragging) {\r\n+          let dragTime = this.dragTime(e)\r\n+          let dragGroupDelta = this.dragGroupDelta(e)\r\n+\r\n+          if (this.props.moveResizeValidator) {\r\n+            dragTime = this.props.moveResizeValidator(\r\n+              'move',\r\n+              this.props.item,\r\n+              dragTime\r\n+            )\r\n+          }\r\n+\r\n+          if (this.props.onDrag) {\r\n+            this.props.onDrag(\r\n+              this.itemId,\r\n+              dragTime,\r\n+              this.props.order + dragGroupDelta\r\n+            )\r\n+          }\r\n+\r\n+          this.setState({\r\n+            dragTime: dragTime,\r\n+            dragGroupDelta: dragGroupDelta\r\n+          })\r\n+        }\r\n+      })\r\n+      .on('dragend', e => {\r\n+        if (this.state.dragging) {\r\n+          if (this.props.onDrop) {\r\n+            let dragTime = this.dragTime(e)\r\n+\r\n+            if (this.props.moveResizeValidator) {\r\n+              dragTime = this.props.moveResizeValidator(\r\n+                'move',\r\n+                this.props.item,\r\n+                dragTime\r\n+              )\r\n+            }\r\n+\r\n+            this.props.onDrop(\r\n+              this.itemId,\r\n+              dragTime,\r\n+              this.props.order + this.dragGroupDelta(e)\r\n+            )\r\n+          }\r\n+\r\n+          this.setState({\r\n+            dragging: false,\r\n+            dragStart: null,\r\n+            preDragPosition: null,\r\n+            dragTime: null,\r\n+            dragGroupDelta: null\r\n+          })\r\n+        }\r\n+      })\r\n+      .on('resizestart', e => {\r\n+        if (this.props.selected) {\r\n+          this.setState({\r\n+            resizing: true,\r\n+            resizeEdge: null, // we don't know yet\r\n+            resizeStart: e.pageX,\r\n+            resizeTime: 0\r\n+          })\r\n+        } else {\r\n+          return false\r\n+        }\r\n+      })\r\n+      .on('resizemove', e => {\r\n+        if (this.state.resizing) {\r\n+          let resizeEdge = this.state.resizeEdge\r\n+\r\n+          if (!resizeEdge) {\r\n+            resizeEdge = e.deltaRect.left !== 0 ? 'left' : 'right'\r\n+            this.setState({ resizeEdge })\r\n+          }\r\n+          const time =\r\n+            resizeEdge === 'left' ? this.itemTimeStart : this.itemTimeEnd\r\n+\r\n+          let resizeTime = this.resizeTimeSnap(\r\n+            time + this.resizeTimeDelta(e, resizeEdge)\r\n+          )\r\n+\r\n+          if (this.props.moveResizeValidator) {\r\n+            resizeTime = this.props.moveResizeValidator(\r\n+              'resize',\r\n+              this.props.item,\r\n+              resizeTime,\r\n+              resizeEdge\r\n+            )\r\n+          }\r\n+\r\n+          if (this.props.onResizing) {\r\n+            this.props.onResizing(this.itemId, resizeTime, resizeEdge)\r\n+          }\r\n+\r\n+          this.setState({\r\n+            resizeTime\r\n+          })\r\n+        }\r\n+      })\r\n+      .on('resizeend', e => {\r\n+        if (this.state.resizing) {\r\n+          const { resizeEdge } = this.state\r\n+          const time =\r\n+            resizeEdge === 'left' ? this.itemTimeStart : this.itemTimeEnd\r\n+          let resizeTime = this.resizeTimeSnap(\r\n+            time + this.resizeTimeDelta(e, resizeEdge)\r\n+          )\r\n+\r\n+          if (this.props.moveResizeValidator) {\r\n+            resizeTime = this.props.moveResizeValidator(\r\n+              'resize',\r\n+              this.props.item,\r\n+              resizeTime,\r\n+              resizeEdge\r\n+            )\r\n+          }\r\n+\r\n+          if (this.props.onResized) {\r\n+            this.props.onResized(\r\n+              this.itemId,\r\n+              resizeTime,\r\n+              resizeEdge,\r\n+              this.resizeTimeDelta(e, resizeEdge)\r\n+            )\r\n+          }\r\n+          this.setState({\r\n+            resizing: null,\r\n+            resizeStart: null,\r\n+            resizeEdge: null,\r\n+            resizeTime: null\r\n+          })\r\n+        }\r\n+      })\r\n+      .on('tap', e => {\r\n+        this.actualClick(e, e.pointerType === 'mouse' ? 'click' : 'touch')\r\n+      })\r\n+\r\n+    this.setState({\r\n+      interactMounted: true\r\n+    })\r\n+  }\r\n+\r\n+  canResizeLeft(props = this.props) {\r\n+    if (!props.canResizeLeft) {\r\n+      return false\r\n+    }\r\n+    let width = parseInt(props.dimensions.width, 10)\r\n+    return width >= props.minResizeWidth\r\n+  }\r\n+\r\n+  canResizeRight(props = this.props) {\r\n+    if (!props.canResizeRight) {\r\n+      return false\r\n+    }\r\n+    let width = parseInt(props.dimensions.width, 10)\r\n+    return width >= props.minResizeWidth\r\n+  }\r\n+\r\n+  canMove(props = this.props) {\r\n+    return !!props.canMove\r\n+  }\r\n+\r\n+  componentWillReceiveProps(nextProps) {\r\n+    this.cacheDataFromProps(nextProps)\r\n+\r\n+    let { interactMounted } = this.state\r\n+    const couldDrag = this.props.selected && this.canMove(this.props)\r\n+    const couldResizeLeft =\r\n+      this.props.selected && this.canResizeLeft(this.props)\r\n+    const couldResizeRight =\r\n+      this.props.selected && this.canResizeRight(this.props)\r\n+    const willBeAbleToDrag = nextProps.selected && this.canMove(nextProps)\r\n+    const willBeAbleToResizeLeft =\r\n+      nextProps.selected && this.canResizeLeft(nextProps)\r\n+    const willBeAbleToResizeRight =\r\n+      nextProps.selected && this.canResizeRight(nextProps)\r\n+\r\n+    if (nextProps.selected && !interactMounted) {\r\n+      this.mountInteract()\r\n+      interactMounted = true\r\n+    }\r\n+\r\n+    if (\r\n+      interactMounted &&\r\n+      (couldResizeLeft !== willBeAbleToResizeLeft ||\r\n+        couldResizeRight !== willBeAbleToResizeRight)\r\n+    ) {\r\n+      const leftResize = this.props.useResizeHandle ? this.dragLeft : true\r\n+      const rightResize = this.props.useResizeHandle ? this.dragRight : true\r\n+\r\n+      interact(this.item).resizable({\r\n+        enabled: willBeAbleToResizeLeft || willBeAbleToResizeRight,\r\n+        edges: {\r\n+          top: false,\r\n+          bottom: false,\r\n+          left: willBeAbleToResizeLeft && leftResize,\r\n+          right: willBeAbleToResizeRight && rightResize\r\n+        }\r\n+      })\r\n+    }\r\n+    if (interactMounted && couldDrag !== willBeAbleToDrag) {\r\n+      interact(this.item).draggable({ enabled: willBeAbleToDrag })\r\n+    }\r\n+  }\r\n+\r\n+  onMouseDown = e => {\r\n+    if (!this.state.interactMounted) {\r\n+      e.preventDefault()\r\n+      this.startedClicking = true\r\n+    }\r\n+  }\r\n+\r\n+  onMouseUp = e => {\r\n+    if (!this.state.interactMounted && this.startedClicking) {\r\n+      this.startedClicking = false\r\n+      this.actualClick(e, 'click')\r\n+    }\r\n+  }\r\n+\r\n+  onTouchStart = e => {\r\n+    if (!this.state.interactMounted) {\r\n+      e.preventDefault()\r\n+      this.startedTouching = true\r\n+    }\r\n+  }\r\n+\r\n+  onTouchEnd = e => {\r\n+    if (!this.state.interactMounted && this.startedTouching) {\r\n+      this.startedTouching = false\r\n+      this.actualClick(e, 'touch')\r\n+    }\r\n+  }\r\n+\r\n+  handleDoubleClick = e => {\r\n+    e.stopPropagation()\r\n+    if (this.props.onItemDoubleClick) {\r\n+      this.props.onItemDoubleClick(this.itemId, e)\r\n+    }\r\n+  }\r\n+\r\n+  handleContextMenu = e => {\r\n+    if (this.props.onContextMenu) {\r\n+      e.preventDefault()\r\n+      e.stopPropagation()\r\n+      this.props.onContextMenu(this.itemId, e)\r\n+    }\r\n+  }\r\n+\r\n+  actualClick(e, clickType) {\r\n+    if (this.props.canSelect && this.props.onSelect) {\r\n+      this.props.onSelect(this.itemId, clickType, e)\r\n+    }\r\n+  }\r\n+\r\n+  getItemRef = el => (this.item = el)\r\n+  getDragLeftRef = el => (this.dragLeft = el)\r\n+  getDragRightRef = el => (this.dragRight = el)\r\n+\r\n+\r\n+  getItemProps = (props = {}) => {\r\n+    //TODO: maybe shouldnt include all of these classes\r\n+    const classNames =\r\n+      'rct-item' +\r\n+      (this.props.selected ? ' selected' : '') +\r\n+      (this.canMove(this.props) ? ' can-move' : '') +\r\n+      (this.canResizeLeft(this.props) || this.canResizeRight(this.props)\r\n+        ? ' can-resize'\r\n+        : '') +\r\n+      (this.canResizeLeft(this.props) ? ' can-resize-left' : '') +\r\n+      (this.canResizeRight(this.props) ? ' can-resize-right' : '') +\r\n+      (this.props.item.className ? ` ${this.props.item.className}` : '')\r\n+\r\n+    const dimensions = this.props.dimensions\r\n+\r\n+    \r\n+    const style = {\r\n+      left: `${dimensions.left}px`,\r\n+      top: `${dimensions.top}px`,\r\n+      width: `${dimensions.width}px`,\r\n+      height: `${dimensions.height}px`,\r\n+      lineHeight: `${dimensions.height}px`\r\n+    }\r\n+\r\n+    return {\r\n+      key: this.itemId,\r\n+      ref: this.getItemRef,\r\n+      className: classNames + ` ${props.className? props.className : ''}`,\r\n+      onMouseDown: composeEvents(this.onMouseDown, props.onMouseDown),\r\n+      onMouseUp: composeEvents(this.onMouseUp, props.onMouseUp),\r\n+      onTouchStart: composeEvents(this.onTouchStart, props.onTouchStart),\r\n+      onTouchEnd: composeEvents(this.onTouchEnd, props.onTouchEnd),\r\n+      onDoubleClick: composeEvents(this.handleDoubleClick, props.onDoubleClick),\r\n+      onContextMenu: composeEvents(this.handleContextMenu, props.composeEvents),\r\n+      style: Object.assign({}, props.style, style),\r\n+    }\r\n+  }\r\n+\r\n+  getResizeProps = (props = {}) => {\r\n+    return {\r\n+      left: {\r\n+        ref: this.getDragLeftRef,\r\n+        className: `rct-drag-left ${props.classNameLeft}`\r\n+      },\r\n+      right: {\r\n+        ref: this.getDragRightRef,\r\n+        className: `rct-drag-right ${props.classNameRight}`\r\n+      }\r\n+    }\r\n+  }\r\n+\r\n+  render() {\r\n+    if (typeof this.props.order === 'undefined' || this.props.order === null) {\r\n+      return null\r\n+    }\r\n+\r\n+    const timelineContext = this.context.getTimelineContext()\r\n+    const itemContext = {\r\n+      dimensions: this.props.dimensions,\r\n+      useResizeHandle: this.props.useResizeHandle,\r\n+      title: this.itemDivTitle,\r\n+      canMove: this.canMove(this.props),\r\n+      canResizeLeft: this.canResizeLeft(this.props),\r\n+      canResizeRight: this.canResizeRight(this.props),\r\n+      selected: this.props.selected,\r\n+      dragging: this.state.dragging,\r\n+      dragStart: this.state.dragStart,\r\n+      dragTime: this.state.dragTime,\r\n+      dragGroupDelta: this.state.dragGroupDelta,\r\n+      resizing: this.state.resizing,\r\n+      resizeEdge: this.state.resizeEdge,\r\n+      resizeStart: this.state.resizeStart,\r\n+      resizeTime: this.state.resizeTime,\r\n+      showInnerContentsRender: this.props.dimensions.width > this.props.minimumWidthForItemContentVisibility,\r","path":"src/lib/items/Item.js","position":null,"original_position":1174,"commit_id":"16b9d56cbd069a77b1288e0cf1ad3c9c2edf2355","original_commit_id":"87263873e8230c82c31859a984b15d9b3a13e744","user":{"login":"Ilaiwi","id":10817089,"node_id":"MDQ6VXNlcjEwODE3MDg5","avatar_url":"https://avatars1.githubusercontent.com/u/10817089?v=4","gravatar_id":"","url":"https://api.github.com/users/Ilaiwi","html_url":"https://github.com/Ilaiwi","followers_url":"https://api.github.com/users/Ilaiwi/followers","following_url":"https://api.github.com/users/Ilaiwi/following{/other_user}","gists_url":"https://api.github.com/users/Ilaiwi/gists{/gist_id}","starred_url":"https://api.github.com/users/Ilaiwi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ilaiwi/subscriptions","organizations_url":"https://api.github.com/users/Ilaiwi/orgs","repos_url":"https://api.github.com/users/Ilaiwi/repos","events_url":"https://api.github.com/users/Ilaiwi/events{/privacy}","received_events_url":"https://api.github.com/users/Ilaiwi/received_events","type":"User","site_admin":false},"body":"I deleted `minimumWidthForItemContentVisibility` as well","created_at":"2018-07-07T12:14:49Z","updated_at":"2018-07-07T12:14:49Z","html_url":"https://github.com/namespace-ee/react-calendar-timeline/pull/308#discussion_r200810817","pull_request_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls/308","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls/comments/200810817"},"html":{"href":"https://github.com/namespace-ee/react-calendar-timeline/pull/308#discussion_r200810817"},"pull_request":{"href":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls/308"}},"in_reply_to_id":199662982},"pull_request":{"url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls/308","id":186587899,"node_id":"MDExOlB1bGxSZXF1ZXN0MTg2NTg3ODk5","html_url":"https://github.com/namespace-ee/react-calendar-timeline/pull/308","diff_url":"https://github.com/namespace-ee/react-calendar-timeline/pull/308.diff","patch_url":"https://github.com/namespace-ee/react-calendar-timeline/pull/308.patch","issue_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/issues/308","number":308,"state":"open","locked":false,"title":"Item renderer","user":{"login":"Ilaiwi","id":10817089,"node_id":"MDQ6VXNlcjEwODE3MDg5","avatar_url":"https://avatars1.githubusercontent.com/u/10817089?v=4","gravatar_id":"","url":"https://api.github.com/users/Ilaiwi","html_url":"https://github.com/Ilaiwi","followers_url":"https://api.github.com/users/Ilaiwi/followers","following_url":"https://api.github.com/users/Ilaiwi/following{/other_user}","gists_url":"https://api.github.com/users/Ilaiwi/gists{/gist_id}","starred_url":"https://api.github.com/users/Ilaiwi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ilaiwi/subscriptions","organizations_url":"https://api.github.com/users/Ilaiwi/orgs","repos_url":"https://api.github.com/users/Ilaiwi/repos","events_url":"https://api.github.com/users/Ilaiwi/events{/privacy}","received_events_url":"https://api.github.com/users/Ilaiwi/received_events","type":"User","site_admin":false},"body":"Rework ItemRenderer to implement renderProp + propGetters patterns. #289 \r\n\r\n- [x] refactor item to use renderProp\r\n- [x] add an example to demo using render props to show the power of the pattern\r\n- [x] edit readme to include the change\r\n- [x] update changelog with breaking changes\r\n\r\n![renderprop](https://user-images.githubusercontent.com/10817089/39751870-4dc50aa2-52c2-11e8-991e-5f312cf3b5a7.gif)\r\n","created_at":"2018-05-08T10:16:13Z","updated_at":"2018-07-07T12:14:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6b5b908c1e1e734abab9a41787de4d6515d626c0","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls/308/commits","review_comments_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls/308/comments","review_comment_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls/comments{/number}","comments_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/issues/308/comments","statuses_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/statuses/16b9d56cbd069a77b1288e0cf1ad3c9c2edf2355","head":{"label":"Ilaiwi:itemRenderer","ref":"itemRenderer","sha":"16b9d56cbd069a77b1288e0cf1ad3c9c2edf2355","user":{"login":"Ilaiwi","id":10817089,"node_id":"MDQ6VXNlcjEwODE3MDg5","avatar_url":"https://avatars1.githubusercontent.com/u/10817089?v=4","gravatar_id":"","url":"https://api.github.com/users/Ilaiwi","html_url":"https://github.com/Ilaiwi","followers_url":"https://api.github.com/users/Ilaiwi/followers","following_url":"https://api.github.com/users/Ilaiwi/following{/other_user}","gists_url":"https://api.github.com/users/Ilaiwi/gists{/gist_id}","starred_url":"https://api.github.com/users/Ilaiwi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ilaiwi/subscriptions","organizations_url":"https://api.github.com/users/Ilaiwi/orgs","repos_url":"https://api.github.com/users/Ilaiwi/repos","events_url":"https://api.github.com/users/Ilaiwi/events{/privacy}","received_events_url":"https://api.github.com/users/Ilaiwi/received_events","type":"User","site_admin":false},"repo":{"id":131467779,"node_id":"MDEwOlJlcG9zaXRvcnkxMzE0Njc3Nzk=","name":"react-calendar-timeline","full_name":"Ilaiwi/react-calendar-timeline","owner":{"login":"Ilaiwi","id":10817089,"node_id":"MDQ6VXNlcjEwODE3MDg5","avatar_url":"https://avatars1.githubusercontent.com/u/10817089?v=4","gravatar_id":"","url":"https://api.github.com/users/Ilaiwi","html_url":"https://github.com/Ilaiwi","followers_url":"https://api.github.com/users/Ilaiwi/followers","following_url":"https://api.github.com/users/Ilaiwi/following{/other_user}","gists_url":"https://api.github.com/users/Ilaiwi/gists{/gist_id}","starred_url":"https://api.github.com/users/Ilaiwi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ilaiwi/subscriptions","organizations_url":"https://api.github.com/users/Ilaiwi/orgs","repos_url":"https://api.github.com/users/Ilaiwi/repos","events_url":"https://api.github.com/users/Ilaiwi/events{/privacy}","received_events_url":"https://api.github.com/users/Ilaiwi/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Ilaiwi/react-calendar-timeline","description":"A modern and responsive react timeline component.","fork":true,"url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline","forks_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/forks","keys_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/teams","hooks_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/hooks","issue_events_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/issues/events{/number}","events_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/events","assignees_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/assignees{/user}","branches_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/branches{/branch}","tags_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/tags","blobs_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/git/refs{/sha}","trees_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/statuses/{sha}","languages_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/languages","stargazers_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/stargazers","contributors_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/contributors","subscribers_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/subscribers","subscription_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/subscription","commits_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/commits{/sha}","git_commits_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/git/commits{/sha}","comments_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/comments{/number}","issue_comment_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/issues/comments{/number}","contents_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/contents/{+path}","compare_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/merges","archive_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/downloads","issues_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/issues{/number}","pulls_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/pulls{/number}","milestones_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/milestones{/number}","notifications_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/labels{/name}","releases_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/releases{/id}","deployments_url":"https://api.github.com/repos/Ilaiwi/react-calendar-timeline/deployments","created_at":"2018-04-29T05:13:12Z","updated_at":"2018-06-25T11:48:17Z","pushed_at":"2018-07-05T12:27:55Z","git_url":"git://github.com/Ilaiwi/react-calendar-timeline.git","ssh_url":"git@github.com:Ilaiwi/react-calendar-timeline.git","clone_url":"https://github.com/Ilaiwi/react-calendar-timeline.git","svn_url":"https://github.com/Ilaiwi/react-calendar-timeline","homepage":"https://namespace-ee.github.io/react-calendar-timeline-docs/","size":6473,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"namespace-ee:develop","ref":"develop","sha":"1cb2631e7e830cf8fde09882638735e7a9281681","user":{"login":"namespace-ee","id":9548946,"node_id":"MDEyOk9yZ2FuaXphdGlvbjk1NDg5NDY=","avatar_url":"https://avatars2.githubusercontent.com/u/9548946?v=4","gravatar_id":"","url":"https://api.github.com/users/namespace-ee","html_url":"https://github.com/namespace-ee","followers_url":"https://api.github.com/users/namespace-ee/followers","following_url":"https://api.github.com/users/namespace-ee/following{/other_user}","gists_url":"https://api.github.com/users/namespace-ee/gists{/gist_id}","starred_url":"https://api.github.com/users/namespace-ee/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/namespace-ee/subscriptions","organizations_url":"https://api.github.com/users/namespace-ee/orgs","repos_url":"https://api.github.com/users/namespace-ee/repos","events_url":"https://api.github.com/users/namespace-ee/events{/privacy}","received_events_url":"https://api.github.com/users/namespace-ee/received_events","type":"Organization","site_admin":false},"repo":{"id":47966876,"node_id":"MDEwOlJlcG9zaXRvcnk0Nzk2Njg3Ng==","name":"react-calendar-timeline","full_name":"namespace-ee/react-calendar-timeline","owner":{"login":"namespace-ee","id":9548946,"node_id":"MDEyOk9yZ2FuaXphdGlvbjk1NDg5NDY=","avatar_url":"https://avatars2.githubusercontent.com/u/9548946?v=4","gravatar_id":"","url":"https://api.github.com/users/namespace-ee","html_url":"https://github.com/namespace-ee","followers_url":"https://api.github.com/users/namespace-ee/followers","following_url":"https://api.github.com/users/namespace-ee/following{/other_user}","gists_url":"https://api.github.com/users/namespace-ee/gists{/gist_id}","starred_url":"https://api.github.com/users/namespace-ee/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/namespace-ee/subscriptions","organizations_url":"https://api.github.com/users/namespace-ee/orgs","repos_url":"https://api.github.com/users/namespace-ee/repos","events_url":"https://api.github.com/users/namespace-ee/events{/privacy}","received_events_url":"https://api.github.com/users/namespace-ee/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/namespace-ee/react-calendar-timeline","description":"A modern and responsive react timeline component.","fork":false,"url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline","forks_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/forks","keys_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/keys{/key_id}","collaborators_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/teams","hooks_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/hooks","issue_events_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/issues/events{/number}","events_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/events","assignees_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/assignees{/user}","branches_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/branches{/branch}","tags_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/tags","blobs_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/git/refs{/sha}","trees_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/git/trees{/sha}","statuses_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/statuses/{sha}","languages_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/languages","stargazers_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/stargazers","contributors_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/contributors","subscribers_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/subscribers","subscription_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/subscription","commits_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/commits{/sha}","git_commits_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/git/commits{/sha}","comments_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/comments{/number}","issue_comment_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/issues/comments{/number}","contents_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/contents/{+path}","compare_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/compare/{base}...{head}","merges_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/merges","archive_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/downloads","issues_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/issues{/number}","pulls_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls{/number}","milestones_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/milestones{/number}","notifications_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/labels{/name}","releases_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/releases{/id}","deployments_url":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/deployments","created_at":"2015-12-14T10:07:15Z","updated_at":"2018-07-07T11:42:33Z","pushed_at":"2018-07-05T12:27:57Z","git_url":"git://github.com/namespace-ee/react-calendar-timeline.git","ssh_url":"git@github.com:namespace-ee/react-calendar-timeline.git","clone_url":"https://github.com/namespace-ee/react-calendar-timeline.git","svn_url":"https://github.com/namespace-ee/react-calendar-timeline","homepage":"https://namespace-ee.github.io/react-calendar-timeline-docs/","size":6171,"stargazers_count":460,"watchers_count":460,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":158,"mirror_url":null,"archived":false,"open_issues_count":37,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":158,"open_issues":37,"watchers":460,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls/308"},"html":{"href":"https://github.com/namespace-ee/react-calendar-timeline/pull/308"},"issue":{"href":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/issues/308"},"comments":{"href":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/issues/308/comments"},"review_comments":{"href":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls/308/comments"},"review_comment":{"href":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/pulls/308/commits"},"statuses":{"href":"https://api.github.com/repos/namespace-ee/react-calendar-timeline/statuses/16b9d56cbd069a77b1288e0cf1ad3c9c2edf2355"}},"author_association":"NONE"}}
{"actor":{"display_login":"Ilaiwi"}}