diff --git a/article.js b/article.js index 446b9c87..b538a9b2 100644 --- a/article.js +++ b/article.js @@ -19,7 +19,7 @@ topStalled:"stalled",topSuspend:"suspend",topTimeUpdate:"timeupdate",topVolumeCh return!0}var r=Object.prototype.hasOwnProperty;e.exports=n},function(e,t,n){"use strict";function r(e){var t=d.getID(e),n=h.getReactRootIDFromNodeID(t),r=d.findReactContainerForID(n),i=d.getFirstReactDOM(r);return i}function i(e,t){this.topLevelType=e,this.nativeEvent=t,this.ancestors=[]}function a(e){o(e)}function o(e){for(var t=d.getFirstReactDOM(m(e.nativeEvent))||window,n=t;n;)e.ancestors.push(n),n=r(n);for(var i=0;i1?s-1:0),u=1;ut.end?(n=t.end,r=t.start):(n=t.start,r=t.end),i.moveToElementText(e),i.moveStart("character",n),i.setEndPoint("EndToStart",i),i.moveEnd("character",r-n),i.select()}function s(e,t){if(window.getSelection){var n=window.getSelection(),r=e[c()].length,i=Math.min(t.start,r),a="undefined"==typeof t.end?i:Math.min(t.end,r);if(!n.extend&&i>a){var o=a;a=i,i=o}var s=u(e,i),l=u(e,a);if(s&&l){var h=document.createRange();h.setStart(s.node,s.offset),n.removeAllRanges(),i>a?(n.addRange(h),n.extend(l.node,l.offset)):(h.setEnd(l.node,l.offset),n.addRange(h))}}}var l=n(10),u=n(129),c=n(76),h=l.canUseDOM&&"selection"in document&&!("getSelection"in window),d={getOffsets:h?i:a,setOffsets:h?o:s};e.exports=d},function(e,t){"use strict";function n(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function r(e){for(;e;){if(e.nextSibling)return e.nextSibling;e=e.parentNode}}function i(e,t){for(var i=n(e),a=0,o=0;i;){if(3===i.nodeType){if(o=a+i.textContent.length,a<=t&&o>=t)return{node:i,offset:t-a};a=o}i=n(r(i))}}e.exports=i},function(e,t){"use strict";function n(){if("undefined"==typeof document)return null;try{return document.activeElement||document.body}catch(e){return document.body}}e.exports=n},function(e,t,n){"use strict";function r(e){if("selectionStart"in e&&l.hasSelectionCapabilities(e))return{start:e.selectionStart,end:e.selectionEnd};if(window.getSelection){var t=window.getSelection();return{anchorNode:t.anchorNode,anchorOffset:t.anchorOffset,focusNode:t.focusNode,focusOffset:t.focusOffset}}if(document.selection){var n=document.selection.createRange();return{parentElement:n.parentElement(),text:n.text,top:n.boundingTop,left:n.boundingLeft}}}function i(e,t){if(b||null==v||v!==c())return null;var n=r(v);if(!w||!p(w,n)){w=n;var i=u.getPooled(g.select,y,e,t);return i.type="select",i.target=v,o.accumulateTwoPhaseDispatches(i),i}return null}var a=n(31),o=n(74),s=n(10),l=n(127),u=n(78),c=n(130),h=n(83),d=n(80),p=n(118),f=a.topLevelTypes,m=s.canUseDOM&&"documentMode"in document&&document.documentMode<=11,g={select:{phasedRegistrationNames:{bubbled:d({onSelect:null}),captured:d({onSelectCapture:null})},dependencies:[f.topBlur,f.topContextMenu,f.topFocus,f.topKeyDown,f.topMouseDown,f.topMouseUp,f.topSelectionChange]}},v=null,y=null,w=null,b=!1,_=!1,x=d({onSelect:null}),E={eventTypes:g,extractEvents:function(e,t,n,r,a){if(!_)return null;switch(e){case f.topFocus:(h(t)||"true"===t.contentEditable)&&(v=t,y=n,w=null);break;case f.topBlur:v=null,y=null,w=null;break;case f.topMouseDown:b=!0;break;case f.topContextMenu:case f.topMouseUp:return b=!1,i(r,a);case f.topSelectionChange:if(m)break;case f.topKeyDown:case f.topKeyUp:return i(r,a)}return null},didPutListener:function(e,t,n){t===x&&(_=!0)}};e.exports=E},function(e,t){"use strict";var n=Math.pow(2,53),r={createReactRootIndex:function(){return Math.ceil(Math.random()*n)}};e.exports=r},function(e,t,n){(function(t){"use strict";var r=n(31),i=n(120),a=n(74),o=n(29),s=n(134),l=n(78),u=n(135),c=n(136),h=n(87),d=n(139),p=n(140),f=n(88),m=n(141),g=n(16),v=n(137),y=n(14),w=n(80),b=r.topLevelTypes,_={abort:{phasedRegistrationNames:{bubbled:w({onAbort:!0}),captured:w({onAbortCapture:!0})}},blur:{phasedRegistrationNames:{bubbled:w({onBlur:!0}),captured:w({onBlurCapture:!0})}},canPlay:{phasedRegistrationNames:{bubbled:w({onCanPlay:!0}),captured:w({onCanPlayCapture:!0})}},canPlayThrough:{phasedRegistrationNames:{bubbled:w({onCanPlayThrough:!0}),captured:w({onCanPlayThroughCapture:!0})}},click:{phasedRegistrationNames:{bubbled:w({onClick:!0}),captured:w({onClickCapture:!0})}},contextMenu:{phasedRegistrationNames:{bubbled:w({onContextMenu:!0}),captured:w({onContextMenuCapture:!0})}},copy:{phasedRegistrationNames:{bubbled:w({onCopy:!0}),captured:w({onCopyCapture:!0})}},cut:{phasedRegistrationNames:{bubbled:w({onCut:!0}),captured:w({onCutCapture:!0})}},doubleClick:{phasedRegistrationNames:{bubbled:w({onDoubleClick:!0}),captured:w({onDoubleClickCapture:!0})}},drag:{phasedRegistrationNames:{bubbled:w({onDrag:!0}),captured:w({onDragCapture:!0})}},dragEnd:{phasedRegistrationNames:{bubbled:w({onDragEnd:!0}),captured:w({onDragEndCapture:!0})}},dragEnter:{phasedRegistrationNames:{bubbled:w({onDragEnter:!0}),captured:w({onDragEnterCapture:!0})}},dragExit:{phasedRegistrationNames:{bubbled:w({onDragExit:!0}),captured:w({onDragExitCapture:!0})}},dragLeave:{phasedRegistrationNames:{bubbled:w({onDragLeave:!0}),captured:w({onDragLeaveCapture:!0})}},dragOver:{phasedRegistrationNames:{bubbled:w({onDragOver:!0}),captured:w({onDragOverCapture:!0})}},dragStart:{phasedRegistrationNames:{bubbled:w({onDragStart:!0}),captured:w({onDragStartCapture:!0})}},drop:{phasedRegistrationNames:{bubbled:w({onDrop:!0}),captured:w({onDropCapture:!0})}},durationChange:{phasedRegistrationNames:{bubbled:w({onDurationChange:!0}),captured:w({onDurationChangeCapture:!0})}},emptied:{phasedRegistrationNames:{bubbled:w({onEmptied:!0}),captured:w({onEmptiedCapture:!0})}},encrypted:{phasedRegistrationNames:{bubbled:w({onEncrypted:!0}),captured:w({onEncryptedCapture:!0})}},ended:{phasedRegistrationNames:{bubbled:w({onEnded:!0}),captured:w({onEndedCapture:!0})}},error:{phasedRegistrationNames:{bubbled:w({onError:!0}),captured:w({onErrorCapture:!0})}},focus:{phasedRegistrationNames:{bubbled:w({onFocus:!0}),captured:w({onFocusCapture:!0})}},input:{phasedRegistrationNames:{bubbled:w({onInput:!0}),captured:w({onInputCapture:!0})}},keyDown:{phasedRegistrationNames:{bubbled:w({onKeyDown:!0}),captured:w({onKeyDownCapture:!0})}},keyPress:{phasedRegistrationNames:{bubbled:w({onKeyPress:!0}),captured:w({onKeyPressCapture:!0})}},keyUp:{phasedRegistrationNames:{bubbled:w({onKeyUp:!0}),captured:w({onKeyUpCapture:!0})}},load:{phasedRegistrationNames:{bubbled:w({onLoad:!0}),captured:w({onLoadCapture:!0})}},loadedData:{phasedRegistrationNames:{bubbled:w({onLoadedData:!0}),captured:w({onLoadedDataCapture:!0})}},loadedMetadata:{phasedRegistrationNames:{bubbled:w({onLoadedMetadata:!0}),captured:w({onLoadedMetadataCapture:!0})}},loadStart:{phasedRegistrationNames:{bubbled:w({onLoadStart:!0}),captured:w({onLoadStartCapture:!0})}},mouseDown:{phasedRegistrationNames:{bubbled:w({onMouseDown:!0}),captured:w({onMouseDownCapture:!0})}},mouseMove:{phasedRegistrationNames:{bubbled:w({onMouseMove:!0}),captured:w({onMouseMoveCapture:!0})}},mouseOut:{phasedRegistrationNames:{bubbled:w({onMouseOut:!0}),captured:w({onMouseOutCapture:!0})}},mouseOver:{phasedRegistrationNames:{bubbled:w({onMouseOver:!0}),captured:w({onMouseOverCapture:!0})}},mouseUp:{phasedRegistrationNames:{bubbled:w({onMouseUp:!0}),captured:w({onMouseUpCapture:!0})}},paste:{phasedRegistrationNames:{bubbled:w({onPaste:!0}),captured:w({onPasteCapture:!0})}},pause:{phasedRegistrationNames:{bubbled:w({onPause:!0}),captured:w({onPauseCapture:!0})}},play:{phasedRegistrationNames:{bubbled:w({onPlay:!0}),captured:w({onPlayCapture:!0})}},playing:{phasedRegistrationNames:{bubbled:w({onPlaying:!0}),captured:w({onPlayingCapture:!0})}},progress:{phasedRegistrationNames:{bubbled:w({onProgress:!0}),captured:w({onProgressCapture:!0})}},rateChange:{phasedRegistrationNames:{bubbled:w({onRateChange:!0}),captured:w({onRateChangeCapture:!0})}},reset:{phasedRegistrationNames:{bubbled:w({onReset:!0}),captured:w({onResetCapture:!0})}},scroll:{phasedRegistrationNames:{bubbled:w({onScroll:!0}),captured:w({onScrollCapture:!0})}},seeked:{phasedRegistrationNames:{bubbled:w({onSeeked:!0}),captured:w({onSeekedCapture:!0})}},seeking:{phasedRegistrationNames:{bubbled:w({onSeeking:!0}),captured:w({onSeekingCapture:!0})}},stalled:{phasedRegistrationNames:{bubbled:w({onStalled:!0}),captured:w({onStalledCapture:!0})}},submit:{phasedRegistrationNames:{bubbled:w({onSubmit:!0}),captured:w({onSubmitCapture:!0})}},suspend:{phasedRegistrationNames:{bubbled:w({onSuspend:!0}),captured:w({onSuspendCapture:!0})}},timeUpdate:{phasedRegistrationNames:{bubbled:w({onTimeUpdate:!0}),captured:w({onTimeUpdateCapture:!0})}},touchCancel:{phasedRegistrationNames:{bubbled:w({onTouchCancel:!0}),captured:w({onTouchCancelCapture:!0})}},touchEnd:{phasedRegistrationNames:{bubbled:w({onTouchEnd:!0}),captured:w({onTouchEndCapture:!0})}},touchMove:{phasedRegistrationNames:{bubbled:w({onTouchMove:!0}),captured:w({onTouchMoveCapture:!0})}},touchStart:{phasedRegistrationNames:{bubbled:w({onTouchStart:!0}),captured:w({onTouchStartCapture:!0})}},volumeChange:{phasedRegistrationNames:{bubbled:w({onVolumeChange:!0}),captured:w({onVolumeChangeCapture:!0})}},waiting:{phasedRegistrationNames:{bubbled:w({onWaiting:!0}),captured:w({onWaitingCapture:!0})}},wheel:{phasedRegistrationNames:{bubbled:w({onWheel:!0}),captured:w({onWheelCapture:!0})}}},x={topAbort:_.abort,topBlur:_.blur,topCanPlay:_.canPlay,topCanPlayThrough:_.canPlayThrough,topClick:_.click,topContextMenu:_.contextMenu,topCopy:_.copy,topCut:_.cut,topDoubleClick:_.doubleClick,topDrag:_.drag,topDragEnd:_.dragEnd,topDragEnter:_.dragEnter,topDragExit:_.dragExit,topDragLeave:_.dragLeave,topDragOver:_.dragOver,topDragStart:_.dragStart,topDrop:_.drop,topDurationChange:_.durationChange,topEmptied:_.emptied,topEncrypted:_.encrypted,topEnded:_.ended,topError:_.error,topFocus:_.focus,topInput:_.input,topKeyDown:_.keyDown,topKeyPress:_.keyPress,topKeyUp:_.keyUp,topLoad:_.load,topLoadedData:_.loadedData,topLoadedMetadata:_.loadedMetadata,topLoadStart:_.loadStart,topMouseDown:_.mouseDown,topMouseMove:_.mouseMove,topMouseOut:_.mouseOut,topMouseOver:_.mouseOver,topMouseUp:_.mouseUp,topPaste:_.paste,topPause:_.pause,topPlay:_.play,topPlaying:_.playing,topProgress:_.progress,topRateChange:_.rateChange,topReset:_.reset,topScroll:_.scroll,topSeeked:_.seeked,topSeeking:_.seeking,topStalled:_.stalled,topSubmit:_.submit,topSuspend:_.suspend,topTimeUpdate:_.timeUpdate,topTouchCancel:_.touchCancel,topTouchEnd:_.touchEnd,topTouchMove:_.touchMove,topTouchStart:_.touchStart,topVolumeChange:_.volumeChange,topWaiting:_.waiting,topWheel:_.wheel};for(var E in x)x[E].dependencies=[E];var C=w({onClick:null}),k={},N={eventTypes:_,extractEvents:function(e,n,r,i,o){var g=x[e];if(!g)return null;var w;switch(e){case b.topAbort:case b.topCanPlay:case b.topCanPlayThrough:case b.topDurationChange:case b.topEmptied:case b.topEncrypted:case b.topEnded:case b.topError:case b.topInput:case b.topLoad:case b.topLoadedData:case b.topLoadedMetadata:case b.topLoadStart:case b.topPause:case b.topPlay:case b.topPlaying:case b.topProgress:case b.topRateChange:case b.topReset:case b.topSeeked:case b.topSeeking:case b.topStalled:case b.topSubmit:case b.topSuspend:case b.topTimeUpdate:case b.topVolumeChange:case b.topWaiting:w=l;break;case b.topKeyPress:if(0===v(i))return null;case b.topKeyDown:case b.topKeyUp:w=c;break;case b.topBlur:case b.topFocus:w=u;break;case b.topClick:if(2===i.button)return null;case b.topContextMenu:case b.topDoubleClick:case b.topMouseDown:case b.topMouseMove:case b.topMouseOut:case b.topMouseOver:case b.topMouseUp:w=h;break;case b.topDrag:case b.topDragEnd:case b.topDragEnter:case b.topDragExit:case b.topDragLeave:case b.topDragOver:case b.topDragStart:case b.topDrop:w=d;break;case b.topTouchCancel:case b.topTouchEnd:case b.topTouchMove:case b.topTouchStart:w=p;break;case b.topScroll:w=f;break;case b.topWheel:w=m;break;case b.topCopy:case b.topCut:case b.topPaste:w=s}w?void 0:"production"!==t.env.NODE_ENV?y(!1,"SimpleEventPlugin: Unhandled event type, `%s`.",e):y(!1);var _=w.getPooled(g,r,i,o);return a.accumulateTwoPhaseDispatches(_),_},didPutListener:function(e,t,n){if(t===C){var r=o.getNode(e);k[e]||(k[e]=i.listen(r,"click",g))}},willDeleteListener:function(e,t){t===C&&(k[e].remove(),delete k[e])}};e.exports=N}).call(t,n(5))},function(e,t,n){"use strict";function r(e,t,n,r){i.call(this,e,t,n,r)}var i=n(78),a={clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){i.call(this,e,t,n,r)}var i=n(88),a={relatedTarget:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){i.call(this,e,t,n,r)}var i=n(88),a=n(137),o=n(138),s=n(89),l={key:o,location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:s,charCode:function(e){return"keypress"===e.type?a(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?a(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}};i.augmentClass(r,l),e.exports=r},function(e,t){"use strict";function n(e){var t,n=e.keyCode;return"charCode"in e?(t=e.charCode,0===t&&13===n&&(t=13)):t=n,t>=32||13===t?t:0}e.exports=n},function(e,t,n){"use strict";function r(e){if(e.key){var t=a[e.key]||e.key;if("Unidentified"!==t)return t}if("keypress"===e.type){var n=i(e);return 13===n?"Enter":String.fromCharCode(n)}return"keydown"===e.type||"keyup"===e.type?o[e.keyCode]||"Unidentified":""}var i=n(137),a={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},o={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"};e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){i.call(this,e,t,n,r)}var i=n(87),a={dataTransfer:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){i.call(this,e,t,n,r)}var i=n(88),a=n(89),o={touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:a};i.augmentClass(r,o),e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){i.call(this,e,t,n,r)}var i=n(87),a={deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:null,deltaMode:null};i.augmentClass(r,a),e.exports=r},function(e,t,n){"use strict";var r=n(24),i=r.injection.MUST_USE_ATTRIBUTE,a={xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace"},o={Properties:{clipPath:i,cx:i,cy:i,d:i,dx:i,dy:i,fill:i,fillOpacity:i,fontFamily:i,fontSize:i,fx:i,fy:i,gradientTransform:i,gradientUnits:i,markerEnd:i,markerMid:i,markerStart:i,offset:i,opacity:i,patternContentUnits:i,patternUnits:i,points:i,preserveAspectRatio:i,r:i,rx:i,ry:i,spreadMethod:i,stopColor:i,stopOpacity:i,stroke:i,strokeDasharray:i,strokeLinecap:i,strokeOpacity:i,strokeWidth:i,textAnchor:i,transform:i,version:i,viewBox:i,x1:i,x2:i,x:i,xlinkActuate:i,xlinkArcrole:i,xlinkHref:i,xlinkRole:i,xlinkShow:i,xlinkTitle:i,xlinkType:i,xmlBase:i,xmlLang:i,xmlSpace:i,y1:i,y2:i,y:i},DOMAttributeNamespaces:{xlinkActuate:a.xlink,xlinkArcrole:a.xlink,xlinkHref:a.xlink,xlinkRole:a.xlink,xlinkShow:a.xlink,xlinkTitle:a.xlink,xlinkType:a.xlink,xmlBase:a.xml,xmlLang:a.xml,xmlSpace:a.xml},DOMAttributeNames:{clipPath:"clip-path",fillOpacity:"fill-opacity",fontFamily:"font-family",fontSize:"font-size",gradientTransform:"gradientTransform",gradientUnits:"gradientUnits",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",patternContentUnits:"patternContentUnits",patternUnits:"patternUnits",preserveAspectRatio:"preserveAspectRatio",spreadMethod:"spreadMethod",stopColor:"stop-color",stopOpacity:"stop-opacity",strokeDasharray:"stroke-dasharray",strokeLinecap:"stroke-linecap",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",textAnchor:"text-anchor",viewBox:"viewBox",xlinkActuate:"xlink:actuate", xlinkArcrole:"xlink:arcrole",xlinkHref:"xlink:href",xlinkRole:"xlink:role",xlinkShow:"xlink:show",xlinkTitle:"xlink:title",xlinkType:"xlink:type",xmlBase:"xml:base",xmlLang:"xml:lang",xmlSpace:"xml:space"}};e.exports=o},function(e,t,n){"use strict";function r(e){return Math.floor(100*e)/100}function i(e,t,n){e[t]=(e[t]||0)+n}var a=n(24),o=n(144),s=n(29),l=n(19),u=n(145),c={_allMeasurements:[],_mountStack:[0],_injected:!1,start:function(){c._injected||l.injection.injectMeasure(c.measure),c._allMeasurements.length=0,l.enableMeasure=!0},stop:function(){l.enableMeasure=!1},getLastMeasurements:function(){return c._allMeasurements},printExclusive:function(e){e=e||c._allMeasurements;var t=o.getExclusiveSummary(e);console.table(t.map(function(e){return{"Component class name":e.componentName,"Total inclusive time (ms)":r(e.inclusive),"Exclusive mount time (ms)":r(e.exclusive),"Exclusive render time (ms)":r(e.render),"Mount time per instance (ms)":r(e.exclusive/e.count),"Render time per instance (ms)":r(e.render/e.count),Instances:e.count}}))},printInclusive:function(e){e=e||c._allMeasurements;var t=o.getInclusiveSummary(e);console.table(t.map(function(e){return{"Owner > component":e.componentName,"Inclusive time (ms)":r(e.time),Instances:e.count}})),console.log("Total time:",o.getTotalTime(e).toFixed(2)+" ms")},getMeasurementsSummaryMap:function(e){var t=o.getInclusiveSummary(e,!0);return t.map(function(e){return{"Owner > component":e.componentName,"Wasted time (ms)":e.time,Instances:e.count}})},printWasted:function(e){e=e||c._allMeasurements,console.table(c.getMeasurementsSummaryMap(e)),console.log("Total time:",o.getTotalTime(e).toFixed(2)+" ms")},printDOM:function(e){e=e||c._allMeasurements;var t=o.getDOMSummary(e);console.table(t.map(function(e){var t={};return t[a.ID_ATTRIBUTE_NAME]=e.id,t.type=e.type,t.args=JSON.stringify(e.args),t})),console.log("Total time:",o.getTotalTime(e).toFixed(2)+" ms")},_recordWrite:function(e,t,n,r){var i=c._allMeasurements[c._allMeasurements.length-1].writes;i[e]=i[e]||[],i[e].push({type:t,time:n,args:r})},measure:function(e,t,n){return function(){for(var r=arguments.length,a=Array(r),o=0;o"},h}}};e.exports=c},function(e,t,n){"use strict";function r(e){for(var t=0,n=0;n=u&&s.push(n[t]);return s.sort(function(e,t){return t.exclusive-e.exclusive}),s}function o(e,t){for(var n,r={},i=0;i "+d.current,r[n]=r[n]||{componentName:n,time:0,count:0},o.inclusive[h]&&(r[n].time+=o.inclusive[h]),o.counts[h]&&(r[n].count+=o.counts[h])}}var p=[];for(n in r)r[n].time>=u&&p.push(r[n]);return p.sort(function(e,t){return t.time-e.time}),p}function s(e){var t={},n=Object.keys(e.writes),r=l({},e.exclusive,e.inclusive);for(var i in r){for(var a=!1,o=0;o0&&(t[i]=!0)}return t}var l=n(40),u=1.2,c={_mountImageIntoNode:"set innerHTML",INSERT_MARKUP:"set innerHTML",MOVE_EXISTING:"move",REMOVE_NODE:"remove",SET_MARKUP:"set innerHTML",TEXT_CONTENT:"set textContent",setValueForProperty:"update attribute",setValueForAttribute:"update attribute",deleteValueForProperty:"remove attribute",setValueForStyles:"update styles",replaceNodeWithMarkup:"replace",updateTextContent:"set textContent"},h={getExclusiveSummary:a,getInclusiveSummary:o,getDOMSummary:i,getTotalTime:r};e.exports=h},function(e,t,n){"use strict";var r,i=n(146);r=i.now?function(){return i.now()}:function(){return Date.now()},e.exports=r},function(e,t,n){"use strict";var r,i=n(10);i.canUseDOM&&(r=window.performance||window.msPerformance||window.webkitPerformance),e.exports=r||{}},function(e,t){"use strict";e.exports="0.14.8"},function(e,t,n){"use strict";var r=n(29);e.exports=r.renderSubtreeIntoContainer},function(e,t,n){"use strict";var r=n(72),i=n(150),a=n(147);r.inject();var o={renderToString:i.renderToString,renderToStaticMarkup:i.renderToStaticMarkup,version:a};e.exports=o},function(e,t,n){(function(t){"use strict";function r(e){o.isValidElement(e)?void 0:"production"!==t.env.NODE_ENV?f(!1,"renderToString(): You must pass a valid ReactElement."):f(!1);var n;try{h.injection.injectBatchingStrategy(u);var r=s.createReactRootID();return n=c.getPooled(!1),n.perform(function(){var t=p(e,null),i=t.mountComponent(r,n,d);return l.addChecksumToMarkup(i)},null)}finally{c.release(n),h.injection.injectBatchingStrategy(a)}}function i(e){o.isValidElement(e)?void 0:"production"!==t.env.NODE_ENV?f(!1,"renderToStaticMarkup(): You must pass a valid ReactElement."):f(!1);var n;try{h.injection.injectBatchingStrategy(u);var r=s.createReactRootID();return n=c.getPooled(!0),n.perform(function(){var t=p(e,null);return t.mountComponent(r,n,d)},null)}finally{c.release(n),h.injection.injectBatchingStrategy(a)}}var a=n(93),o=n(43),s=n(46),l=n(49),u=n(151),c=n(152),h=n(55),d=n(59),p=n(63),f=n(14);e.exports={renderToString:r,renderToStaticMarkup:i}}).call(t,n(5))},function(e,t){"use strict";var n={isBatchingUpdates:!1,batchedUpdates:function(e){}};e.exports=n},function(e,t,n){"use strict";function r(e){this.reinitializeTransaction(),this.renderToStaticMarkup=e,this.reactMountReady=a.getPooled(null),this.useCreateElement=!1}var i=n(57),a=n(56),o=n(58),s=n(40),l=n(16),u={initialize:function(){this.reactMountReady.reset()},close:l},c=[u],h={getTransactionWrappers:function(){return c},getReactMountReady:function(){return this.reactMountReady},destructor:function(){a.release(this.reactMountReady),this.reactMountReady=null}};s(r.prototype,o.Mixin,h),i.addPoolingTo(r),e.exports=r},function(e,t,n){(function(t){"use strict";var r=n(111),i=n(124),a=n(123),o=n(154),s=n(43),l=n(155),u=n(108),c=n(147),h=n(40),d=n(157),p=s.createElement,f=s.createFactory,m=s.cloneElement;"production"!==t.env.NODE_ENV&&(p=l.createElement,f=l.createFactory,m=l.cloneElement);var g={Children:{map:r.map,forEach:r.forEach,count:r.count,toArray:r.toArray,only:d},Component:i,createElement:p,cloneElement:m,isValidElement:s.isValidElement,PropTypes:u,createClass:a.createClass,createFactory:f,createMixin:function(e){return e},DOM:o,version:c,__spread:h};e.exports=g}).call(t,n(5))},function(e,t,n){(function(t){"use strict";function r(e){return"production"!==t.env.NODE_ENV?a.createFactory(e):i.createFactory(e)}var i=n(43),a=n(155),o=n(156),s=o({a:"a",abbr:"abbr",address:"address",area:"area",article:"article",aside:"aside",audio:"audio",b:"b",base:"base",bdi:"bdi",bdo:"bdo",big:"big",blockquote:"blockquote",body:"body",br:"br",button:"button",canvas:"canvas",caption:"caption",cite:"cite",code:"code",col:"col",colgroup:"colgroup",data:"data",datalist:"datalist",dd:"dd",del:"del",details:"details",dfn:"dfn",dialog:"dialog",div:"div",dl:"dl",dt:"dt",em:"em",embed:"embed",fieldset:"fieldset",figcaption:"figcaption",figure:"figure",footer:"footer",form:"form",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",h6:"h6",head:"head",header:"header",hgroup:"hgroup",hr:"hr",html:"html",i:"i",iframe:"iframe",img:"img",input:"input",ins:"ins",kbd:"kbd",keygen:"keygen",label:"label",legend:"legend",li:"li",link:"link",main:"main",map:"map",mark:"mark",menu:"menu",menuitem:"menuitem",meta:"meta",meter:"meter",nav:"nav",noscript:"noscript",object:"object",ol:"ol",optgroup:"optgroup",option:"option",output:"output",p:"p",param:"param",picture:"picture",pre:"pre",progress:"progress",q:"q",rp:"rp",rt:"rt",ruby:"ruby",s:"s",samp:"samp",script:"script",section:"section",select:"select",small:"small",source:"source",span:"span",strong:"strong",style:"style",sub:"sub",summary:"summary",sup:"sup",table:"table",tbody:"tbody",td:"td",textarea:"textarea",tfoot:"tfoot",th:"th",thead:"thead",time:"time",title:"title",tr:"tr",track:"track",u:"u",ul:"ul","var":"var",video:"video",wbr:"wbr",circle:"circle",clipPath:"clipPath",defs:"defs",ellipse:"ellipse",g:"g",image:"image",line:"line",linearGradient:"linearGradient",mask:"mask",path:"path",pattern:"pattern",polygon:"polygon",polyline:"polyline",radialGradient:"radialGradient",rect:"rect",stop:"stop",svg:"svg",text:"text",tspan:"tspan"},r);e.exports=s}).call(t,n(5))},function(e,t,n){(function(t){"use strict";function r(){if(d.current){var e=d.current.getName();if(e)return" Check the render method of `"+e+"`."}return""}function i(e,n){if(e._store&&!e._store.validated&&null==e.key){e._store.validated=!0;var r=a("uniqueKey",e,n);null!==r&&("production"!==t.env.NODE_ENV?g(!1,'Each child in an array or iterator should have a unique "key" prop.%s%s%s',r.parentOrOwner||"",r.childOwner||"",r.url||""):void 0)}}function a(e,t,n){var i=r();if(!i){var a="string"==typeof n?n:n.displayName||n.name;a&&(i=" Check the top-level render call using <"+a+">.")}var o=v[e]||(v[e]={});if(o[i])return null;o[i]=!0;var s={parentOrOwner:i,url:" See https://fb.me/react-warning-keys for more information.",childOwner:null};return t&&t._owner&&t._owner!==d.current&&(s.childOwner=" It was passed a child from "+t._owner.getName()+"."),s}function o(e,t){if("object"==typeof e)if(Array.isArray(e))for(var n=0;n-1&&{to:s[e],title:o[s[e]].getDefaultProps().title};var t=this.props.next;return t=t=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var l=Object.assign||function(e){for(var t=1;t; it will be ignored"):void 0,"production"!==r.env.NODE_ENV?c["default"]((e.routes||e.children)===(this.props.routes||this.props.children),"You cannot change ; it will be ignored"):void 0},t.prototype.componentWillUnmount=function(){this._unlisten&&this._unlisten()},t.prototype.render=function(){var e=this.state,n=e.location,r=e.routes,i=e.params,o=e.components,s=this.props,u=s.RoutingContext,c=s.createElement,h=a(s,["RoutingContext","createElement"]);return null==n?null:(Object.keys(t.propTypes).forEach(function(e){return delete h[e]}),d["default"].createElement(u,l({},h,{history:this.history,createElement:c,location:n,routes:r,params:i,components:o})))},t}(h.Component);C.propTypes={history:E,children:b.routes,routes:b.routes,RoutingContext:x.isRequired,createElement:x,onError:x,onUpdate:x,parseQueryString:x,stringifyQuery:x},C.defaultProps={RoutingContext:v["default"]},t["default"]=C,e.exports=t["default"]}).call(t,n(5))},function(e,t,n){(function(t){"use strict";var n=function(){};"production"!==t.env.NODE_ENV&&(n=function(e,t,n){var r=arguments.length;n=new Array(r>2?r-2:0);for(var i=2;i0&&"number"!=typeof e[0]))}function a(e,t,n){var a,c;if(r(e)||r(t))return!1;if(e.prototype!==t.prototype)return!1; if(l(e))return!!l(t)&&(e=o.call(e),t=o.call(t),u(e,t,n));if(i(e)){if(!i(t))return!1;if(e.length!==t.length)return!1;for(a=0;a=0;a--)if(h[a]!=d[a])return!1;for(a=h.length-1;a>=0;a--)if(c=h[a],!u(e[c],t[c],n))return!1;return typeof e==typeof t}var o=Array.prototype.slice,s=n(177),l=n(178),u=e.exports=function(e,t,n){return n||(n={}),e===t||(e instanceof Date&&t instanceof Date?e.getTime()===t.getTime():!e||!t||"object"!=typeof e&&"object"!=typeof t?n.strict?e===t:e==t:a(e,t,n))}},function(e,t){function n(e){var t=[];for(var n in e)t.push(n);return t}t=e.exports="function"==typeof Object.keys?Object.keys:n,t.shim=n},function(e,t){function n(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function r(e){return e&&"object"==typeof e&&"number"==typeof e.length&&Object.prototype.hasOwnProperty.call(e,"callee")&&!Object.prototype.propertyIsEnumerable.call(e,"callee")||!1}var i="[object Arguments]"==function(){return Object.prototype.toString.call(arguments)}();t=e.exports=i?n:r,t.supported=n,t.unsupported=r},function(e,t){"use strict";function n(e,t,n){function r(){o=!0,n.apply(this,arguments)}function i(){o||(a0?void 0:"production"!==e.env.NODE_ENV?p["default"](!1,'Missing splat #%s for path "%s"',l,t):p["default"](!1),null!=h&&(o+=encodeURI(h))):"("===u?a+=1:")"===u?a-=1:":"===u.charAt(0)?(c=u.substring(1),h=n[c],null!=h||a>0?void 0:"production"!==e.env.NODE_ENV?p["default"](!1,'Missing "%s" parameter for path "%s"',c,t):p["default"](!1),null!=h&&(o+=encodeURIComponent(h))):o+=u;return o.replace(/\/+/g,"/")}t.__esModule=!0,t.compilePattern=s,t.matchPattern=l,t.getParamNames=u,t.getParams=c,t.formatPattern=h;var d=n(169),p=r(d),f={}}).call(t,n(5))},function(e,t,n){(function(r){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}function a(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function o(e){for(var t in e)if(e.hasOwnProperty(t))return!0;return!1}function s(e){return function(){function t(e,t){var n=!(arguments.length<=2||void 0===arguments[2])&&arguments[2];return y["default"](e,t,n,S.location,S.routes,S.params)}function n(e){var t=e.pathname,n=e.query,r=e.state;return N.createLocation(N.createPath(t,n),r,h.REPLACE)}function i(e,t){P&&P.location===e?s(P,t):x["default"](C,e,function(n,r){n?t(n):r?s(l({},r,{location:e}),t):t()})}function s(e,t){var r=m["default"](S,e),i=r.leaveRoutes,a=r.enterRoutes;g.runLeaveHooks(i),g.runEnterHooks(a,e,function(r,i){r?t(r):i?t(null,n(i)):b["default"](e,function(n,r){n?t(n):t(null,null,S=l({},e,{components:r}))})})}function u(e){return e.__id__||(e.__id__=D++)}function d(e){return e.reduce(function(e,t){return e.push.apply(e,O[u(t)]),e},[])}function f(e,t){x["default"](C,e,function(n,r){if(null==r)return void t();P=l({},r,{location:e});for(var i=d(m["default"](S,P).leaveRoutes),a=void 0,o=0,s=i.length;null==a&&o=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function o(e){return d.stringify(e).replace(/%20/g,"+")}function s(e){for(var t in e)if(e.hasOwnProperty(t)&&"object"==typeof e[t]&&!Array.isArray(e[t])&&null!==e[t])return!0;return!1}function l(e){return function(){function t(e){if(null==e.query){var t=e.search;e.query=k(t.substring(1)),e[w]={search:t,searchBase:""}}return e}function n(e,t){var n,i=void 0;if(!t||""===(i=C(t)))return e;"production"!==r.env.NODE_ENV?h["default"](C!==o||!s(t),"useQueries does not stringify nested query objects by default; use a custom stringifyQuery function"):void 0,"string"==typeof e&&(e=g["default"](e));var a=e[w],l=void 0;l=a&&e.search===a.search?a.searchBase:e.search||"";var c=l+(l?"&":"?")+i;return u({},e,(n={search:c},n[w]={search:c,searchBase:l},n))}function i(e){return S.listenBefore(function(n,r){f["default"](e,t(n),r)})}function l(e){return S.listen(function(n){e(t(n))})}function c(e){S.push(n(e,e.query))}function d(e){S.replace(n(e,e.query))}function p(e,t){return S.createPath(n(e,t||e.query))}function m(e,t){return S.createHref(n(e,t||e.query))}function v(){return t(S.createLocation.apply(S,arguments))}function _(e,t,n){"string"==typeof t&&(t=g["default"](t)),c(u({state:e},t,{query:n}))}function x(e,t,n){"string"==typeof t&&(t=g["default"](t)),d(u({state:e},t,{query:n}))}var E=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],C=E.stringifyQuery,k=E.parseQueryString,N=a(E,["stringifyQuery","parseQueryString"]),S=e(N);return"function"!=typeof C&&(C=o),"function"!=typeof k&&(k=b),u({},S,{listenBefore:i,listen:l,push:c,replace:d,createPath:p,createHref:m,createLocation:v,pushState:y["default"](_,"pushState is deprecated; use push instead"),replaceState:y["default"](x,"replaceState is deprecated; use replace instead")})}}t.__esModule=!0;var u=Object.assign||function(e){for(var t=1;t should not have a "'+t+'" prop')}t.__esModule=!0,t.falsy=r;var i=n(2),a=i.PropTypes.func,o=i.PropTypes.object,s=i.PropTypes.arrayOf,l=i.PropTypes.oneOfType,u=i.PropTypes.element,c=i.PropTypes.shape,h=i.PropTypes.string,d=c({listen:a.isRequired,pushState:a.isRequired,replaceState:a.isRequired,go:a.isRequired});t.history=d;var p=c({pathname:h.isRequired,search:h.isRequired,state:o,action:h.isRequired,key:h});t.location=p;var f=l([a,h]);t.component=f;var m=l([f,o]);t.components=m;var g=l([o,u]);t.route=g;var v=l([g,s(g)]);t.routes=v,t["default"]={falsy:r,history:d,location:p,component:f,components:m,route:g}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function s(e){return 0===e.button}function l(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function u(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0}t.__esModule=!0;var c=Object.assign||function(e){for(var t=1;t elements are for router configuration only and should not be rendered"):c["default"](!1)},t}(h.Component);w.propTypes={to:v.isRequired,query:y,state:y,onEnter:m.falsy,children:m.falsy},w.createRouteFromReactElement=function(e,t){t?t.indexRoute=f["default"].createRouteFromReactElement(e):"production"!==r.env.NODE_ENV?l["default"](!1,"An does not make sense at the root of your route config"):void 0},t["default"]=w,e.exports=t["default"]}).call(t,n(5))},function(e,t,n){(function(r){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var s=n(169),l=i(s),u=n(2),c=i(u),h=n(185),d=n(188),p=n(199),f=c["default"].PropTypes,m=f.string,g=f.object,v=function(e){function t(){a(this,t),e.apply(this,arguments)}return o(t,e),t.prototype.render=function(){"production"!==r.env.NODE_ENV?l["default"](!1," elements are for router configuration only and should not be rendered"):l["default"](!1)},t}(u.Component);v.createRouteFromReactElement=function(e){var t=h.createRouteFromReactElement(e);return t.from&&(t.path=t.from),t.onEnter=function(e,n){var r=e.location,i=e.params,a=void 0;if("/"===t.to.charAt(0))a=d.formatPattern(t.to,i);else if(t.to){var o=e.routes.indexOf(t),s=v.getRoutePattern(e.routes,o-1),l=s.replace(/\/*$/,"/")+t.to;a=d.formatPattern(l,i)}else a=r.pathname;n(t.state||r.state,a,t.query||r.query)},t},v.getRoutePattern=function(e,t){for(var n="",r=t;r>=0;r--){var i=e[r],a=i.path||"";if(n=a.replace(/\/*$/,"/")+n,0===a.indexOf("/"))break}return"/"+n},v.propTypes={path:m,from:m,to:m.isRequired,query:g,state:g,onEnter:p.falsy,children:p.falsy},t["default"]=v,e.exports=t["default"]}).call(t,n(5))},function(e,t,n){(function(r){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var s=n(167),l=i(s),u=n(169),c=i(u),h=n(2),d=i(h),p=n(185),f=n(199),m=d["default"].PropTypes.func,g=function(e){function t(){a(this,t),e.apply(this,arguments)}return o(t,e),t.prototype.render=function(){"production"!==r.env.NODE_ENV?c["default"](!1," elements are for router configuration only and should not be rendered"):c["default"](!1)},t}(h.Component);g.propTypes={path:f.falsy,component:f.component,components:f.components,getComponent:m,getComponents:m},g.createRouteFromReactElement=function(e,t){t?t.indexRoute=p.createRouteFromReactElement(e):"production"!==r.env.NODE_ENV?l["default"](!1,"An does not make sense at the root of your route config"):void 0},t["default"]=g,e.exports=t["default"]}).call(t,n(5))},function(e,t,n){(function(r){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var s=n(169),l=i(s),u=n(2),c=i(u),h=n(185),d=n(199),p=c["default"].PropTypes,f=p.string,m=p.func,g=function(e){function t(){a(this,t),e.apply(this,arguments)}return o(t,e),t.prototype.render=function(){"production"!==r.env.NODE_ENV?l["default"](!1," elements are for router configuration only and should not be rendered"):l["default"](!1)},t}(u.Component);g.createRouteFromReactElement=h.createRouteFromReactElement,g.propTypes={path:f,component:d.component,components:d.components,getComponent:m,getComponents:m},t["default"]=g,e.exports=t["default"]}).call(t,n(5))},function(e,t,n){"use strict";t.__esModule=!0;var r=n(199),i={contextTypes:{history:r.history},componentWillMount:function(){this.history=this.context.history}};t["default"]=i,e.exports=t["default"]},function(e,t,n){(function(r){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}t.__esModule=!0;var a=n(2),o=i(a),s=n(169),l=i(s),u=o["default"].PropTypes.object,c={contextTypes:{history:u.isRequired,route:u},propTypes:{route:u},componentDidMount:function(){this.routerWillLeave?void 0:"production"!==r.env.NODE_ENV?l["default"](!1,"The Lifecycle mixin requires you to define a routerWillLeave method"):l["default"](!1);var e=this.props.route||this.context.route;e?void 0:"production"!==r.env.NODE_ENV?l["default"](!1,"The Lifecycle mixin must be used on either a) a or b) a descendant of a that uses the RouteContext mixin"):l["default"](!1),this._unlistenBeforeLeavingRoute=this.context.history.listenBeforeLeavingRoute(e,this.routerWillLeave)},componentWillUnmount:function(){this._unlistenBeforeLeavingRoute&&this._unlistenBeforeLeavingRoute()}};t["default"]=c,e.exports=t["default"]}).call(t,n(5))},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}t.__esModule=!0;var i=n(2),a=r(i),o=a["default"].PropTypes.object,s={propTypes:{route:o.isRequired},childContextTypes:{route:o.isRequired},getChildContext:function(){return{route:this.props.route}}};t["default"]=s,e.exports=t["default"]},function(e,t,n){(function(r){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}function a(e,t){var n=e.routes,i=e.location,a=e.parseQueryString,s=e.stringifyQuery,u=e.basename;i?void 0:"production"!==r.env.NODE_ENV?l["default"](!1,"match needs a location"):l["default"](!1);var c=g({routes:p.createRoutes(n),parseQueryString:a,stringifyQuery:s,basename:u});"string"==typeof i&&(i=c.createLocation(i)),c.match(i,function(e,n,r){t(e,n,r&&o({},r,{history:c}))})}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t=0&&t=0&&y= 0 and < %s, was %s",v.length,y):h["default"](!1);var w=a(v);return p}t.__esModule=!0;var s=Object.assign||function(e){for(var t=1;t=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e){return function(){function t(e){return b&&null==e.basename&&(0===e.pathname.indexOf(b)?(e.pathname=e.pathname.substring(b.length),e.basename=b,""===e.pathname&&(e.pathname="/")):e.basename=""),e}function n(e){if(!b)return e;"string"==typeof e&&(e=p["default"](e));var t=e.pathname,n="/"===b.slice(-1)?b:b+"/",r="/"===t.charAt(0)?t.slice(1):t,i=n+r;return o({},e,{pathname:i})}function r(e){return x.listenBefore(function(n,r){u["default"](e,t(n),r)})}function a(e){return x.listen(function(n){e(t(n))})}function l(e){x.push(n(e))}function c(e){x.replace(n(e))}function d(e){return x.createPath(n(e))}function f(e){return x.createHref(n(e))}function g(){return t(x.createLocation.apply(x,arguments))}function v(e,t){"string"==typeof t&&(t=p["default"](t)),l(o({state:e},t))}function y(e,t){"string"==typeof t&&(t=p["default"](t)),c(o({state:e},t))}var w=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],b=w.basename,_=i(w,["basename"]),x=e(_);if(null==b&&s.canUseDOM){var E=document.getElementsByTagName("base")[0];E&&(b=h["default"](E.href))}return o({},x,{listenBefore:r,listen:a,push:l,replace:c,createPath:d,createHref:f,createLocation:g,pushState:m["default"](v,"pushState is deprecated; use push instead"),replaceState:m["default"](y,"replaceState is deprecated; use replace instead")})}}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t-1){n.update();break}}else this.curve&&this.curve.update&&this.curve.update()}this.props.onMouseMove&&this.props.onMouseMove(e,this),this.dragging&&this.props.onMouseDrag&&this.props.onMouseDrag(e,this),this.props["static"]||this.playing||!this.props.draw||this.props.draw(this,this.curve)},mouseUp:function(e){return this.down=!1,this.movingPoint?(this.movingPoint=!1,this.mp=!1,void(this.props.onMouseUp&&this.props.onMouseUp(e,this))):void(this.props.onMouseUp&&this.props.onMouseUp(e,this))},onClick:function(e){o(e),this.mx=e.offsetX,this.my=e.offsetY,!this.dragging&&this.props.onClick&&this.props.onClick(e,this)},onKeyUp:function(e){this.props.onKeyUp&&(this.props.onKeyUp(e,this),!this.playing&&this.props.draw&&this.props.draw(this,this.curve))},onKeyDown:function(e){this.props.onKeyDown&&(this.props.onKeyDown(e,this),!this.playing&&this.props.draw&&this.props.draw(this,this.curve))},onKeyPress:function(e){this.props.onKeyPress&&(this.props.onKeyPress(e,this),!this.playing&&this.props.draw&&this.props.draw(this,this.curve))},reset:function(){this.refs.canvas.width=this.refs.canvas.width,this.ctx.strokeStyle="black",this.ctx.lineWidth=1,this.ctx.fillStyle="none",this.offset={x:0,y:0},this.colorSeed=0},setSize:function(e,t){this.defaultWidth=e,this.defaultHeight=t,this.refs.canvas.width=e,this.refs.canvas.height=t},setCurves:function(e){this.setCurve(e)},setCurve:function(e){var t=[];e=e instanceof Array?e:Array.prototype.slice.call(arguments),e.forEach(function(e){t=t.concat(e.points)}),this.curve=1===e.length?e[0]:e,this.lpts=t},getPanelWidth:function(){return this.defaultWidth},getPanelHeight:function(){return this.defaultHeight},getDefaultQuadratic:function(){return new this.Bezier(70,250,20,110,250,60)},getDefaultCubic:function(){return new this.Bezier(120,160,35,200,220,260,220,40)},toImage:function(){var e=this.refs.canvas.toDataURL(),t=new Image;return t.src=e,t},setPanelCount:function(e){var t=this.refs.canvas;t.width=e*this.defaultWidth},setOffset:function(e){this.offset=e},setColor:function(e){this.ctx.strokeStyle=e},getColor:function(){return this.ctx.strokeStyle||"black"},setWeight:function(e){this.ctx.lineWidth=e},noColor:function(e){this.ctx.strokeStyle="transparent"},setRandomColor:function(e){e="undefined"==typeof e?1:e;var t=this.colorSeed%360,n=1,r=.34;this.colorSeed+=87,this.ctx.strokeStyle=i.hsl(t,n,r).alpha(e).css()},setRandomFill:function(e){e="undefined"==typeof e?1:e;var t=this.colorSeed%360,n=1,r=.34;this.colorSeed+=87,this.ctx.fillStyle=i.hsl(t,n,r).alpha(e).css()},setFill:function(e){this.ctx.fillStyle=e},getFill:function(){return this.ctx.fillStyle||"transparent"},noFill:function(){this.ctx.fillStyle="transparent"},drawSkeleton:function(e,t,n){t=t||{x:0,y:0};var r=e.points;if(r.length>2){this.ctx.strokeStyle="lightgrey",this.drawLine(r[0],r[1],t);for(var i=r.length-2,a=1;a=0&&y= 0 and < %s, was %s",v.length,y):h["default"](!1);var w=a(v);return p}t.__esModule=!0;var s=Object.assign||function(e){for(var t=1;t=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}function a(e){return function(){function t(e){return b&&null==e.basename&&(0===e.pathname.indexOf(b)?(e.pathname=e.pathname.substring(b.length),e.basename=b,""===e.pathname&&(e.pathname="/")):e.basename=""),e}function n(e){if(!b)return e;"string"==typeof e&&(e=p["default"](e));var t=e.pathname,n="/"===b.slice(-1)?b:b+"/",r="/"===t.charAt(0)?t.slice(1):t,i=n+r;return o({},e,{pathname:i})}function r(e){return x.listenBefore(function(n,r){u["default"](e,t(n),r)})}function a(e){return x.listen(function(n){e(t(n))})}function l(e){x.push(n(e))}function c(e){x.replace(n(e))}function d(e){return x.createPath(n(e))}function f(e){return x.createHref(n(e))}function g(){return t(x.createLocation.apply(x,arguments))}function v(e,t){"string"==typeof t&&(t=p["default"](t)),l(o({state:e},t))}function y(e,t){"string"==typeof t&&(t=p["default"](t)),c(o({state:e},t))}var w=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],b=w.basename,_=i(w,["basename"]),x=e(_);if(null==b&&s.canUseDOM){var E=document.getElementsByTagName("base")[0];E&&(b=h["default"](E.href))}return o({},x,{listenBefore:r,listen:a,push:l,replace:c,createPath:d,createHref:f,createLocation:g,pushState:m["default"](v,"pushState is deprecated; use push instead"),replaceState:m["default"](y,"replaceState is deprecated; use replace instead")})}}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t-1){n.update();break}}else this.curve&&this.curve.update&&this.curve.update()}this.props.onMouseMove&&this.props.onMouseMove(e,this),this.dragging&&this.props.onMouseDrag&&this.props.onMouseDrag(e,this),this.props["static"]||this.playing||!this.props.draw||this.props.draw(this,this.curve)},mouseUp:function(e){return this.down=!1,this.movingPoint?(this.movingPoint=!1,this.mp=!1,void(this.props.onMouseUp&&this.props.onMouseUp(e,this))):void(this.props.onMouseUp&&this.props.onMouseUp(e,this))},onClick:function(e){o(e),this.mx=e.offsetX,this.my=e.offsetY,!this.dragging&&this.props.onClick&&this.props.onClick(e,this)},onKeyUp:function(e){this.props.onKeyUp&&(this.props.onKeyUp(e,this),!this.playing&&this.props.draw&&this.props.draw(this,this.curve))},onKeyDown:function(e){this.props.onKeyDown&&(this.props.onKeyDown(e,this),!this.playing&&this.props.draw&&this.props.draw(this,this.curve))},onKeyPress:function(e){this.props.onKeyPress&&(this.props.onKeyPress(e,this),!this.playing&&this.props.draw&&this.props.draw(this,this.curve))},reset:function(){this.refs.canvas.width=this.refs.canvas.width,this.ctx.strokeStyle="black",this.ctx.lineWidth=1,this.ctx.fillStyle="none",this.offset={x:0,y:0},this.colorSeed=0},setSize:function(e,t){this.defaultWidth=e,this.defaultHeight=t,this.refs.canvas.width=e,this.refs.canvas.height=t},setCurves:function(e){this.setCurve(e)},setCurve:function(e){var t=[];e=e instanceof Array?e:Array.prototype.slice.call(arguments),e.forEach(function(e){t=t.concat(e.points)}),this.curve=1===e.length?e[0]:e,this.lpts=t},getPanelWidth:function(){return this.defaultWidth},getPanelHeight:function(){return this.defaultHeight},getDefaultQuadratic:function(){return new this.Bezier(70,250,20,110,250,60)},getDefaultCubic:function(){return new this.Bezier(120,160,35,200,220,260,220,40)},toImage:function(){var e=this.refs.canvas.toDataURL(),t=new Image;return t.src=e,t},setPanelCount:function(e){var t=this.refs.canvas;t.width=e*this.defaultWidth},setOffset:function(e){this.offset=e},setColor:function(e){this.ctx.strokeStyle=e},getColor:function(){return this.ctx.strokeStyle||"black"},setWeight:function(e){this.ctx.lineWidth=e},noColor:function(e){this.ctx.strokeStyle="transparent"},setRandomColor:function(e){e="undefined"==typeof e?1:e;var t=this.colorSeed%360,n=1,r=.34;this.colorSeed+=87,this.ctx.strokeStyle=i.hsl(t,n,r).alpha(e).css()},setRandomFill:function(e){e="undefined"==typeof e?1:e;var t=this.colorSeed%360,n=1,r=.34;this.colorSeed+=87,this.ctx.fillStyle=i.hsl(t,n,r).alpha(e).css()},setFill:function(e){this.ctx.fillStyle=e},getFill:function(){return this.ctx.fillStyle||"transparent"},noFill:function(){this.ctx.fillStyle="transparent"},drawSkeleton:function(e,t,n){t=t||{x:0,y:0};var r=e.points;if(r.length>2){this.ctx.strokeStyle="lightgrey",this.drawLine(r[0],r[1],t);for(var i=r.length-2,a=1;at.w/2)){var i=Math.atan2(r,n);i<0&&(i=2*Math.PI+i);var a=t.curve.points,u=t.r,c=4*l(i/4)/3;a[1]={x:t.w/2+u,y:t.w/2+u*c},a[2]={x:t.w/2+t.r*(s(i)+c*o(i)),y:t.w/2+t.r*(o(i)-c*s(i))},a[3]={x:t.w/2+t.r*s(i),y:t.w/2+t.r*o(i)},t.setCurve(new t.Bezier(a)),t.angle=i}},drawCircle:function(e){e.setSize(325,325),e.reset();var t=e.getPanelWidth(),n=e.getPanelHeight(),r=60,i=t/2-r,a=.55228,o={x:-r/2,y:-r/4},s=new e.Bezier([{x:t/2+i,y:n/2},{x:t/2+i,y:n/2+a*i},{x:t/2+a*i,y:n/2+i},{x:t/2,y:n/2+i}]);e.setColor("lightgrey"),e.drawLine({x:0,y:n/2},{x:t+r,y:n/2},o),e.drawLine({x:t/2,y:0},{x:t/2,y:n+r},o);var l=s.points;e.setColor("red"),e.drawPoint(l[0],o),e.drawPoint(l[1],o),e.drawPoint(l[2],o),e.drawPoint(l[3],o),e.drawCurve(s,o),e.setColor("rgb(255,160,160)"),e.drawLine(l[0],l[1],o),e.drawLine(l[1],l[2],o),e.drawLine(l[2],l[3],o),e.setFill("red"),e.text(l[0].x-t/2+","+(l[0].y-n/2),{x:l[0].x+7,y:l[0].y+3},o),e.text(l[1].x-t/2+","+(l[1].y-n/2),{x:l[1].x+7,y:l[1].y+3},o),e.text(l[2].x-t/2+","+(l[2].y-n/2),{x:l[2].x+7,y:l[2].y+7},o),e.text(l[3].x-t/2+","+(l[3].y-n/2),{x:l[3].x,y:l[3].y+13},o),l.forEach(function(e){e.x=-(e.x-t)}),e.setColor("blue"),e.drawCurve(s,o),e.drawLine(l[2],l[3],o),e.drawPoint(l[2],o),e.setFill("blue"),e.text("reflected",{x:l[2].x-r/2,y:l[2].y+13},o),e.setColor("rgb(200,200,255)"),e.drawLine(l[1],l[0],o),e.drawPoint(l[1],o),l.forEach(function(e){e.y=-(e.y-n)}),e.setColor("green"),e.drawCurve(s,o),l.forEach(function(e){e.x=-(e.x-t)}),e.setColor("purple"),e.drawCurve(s,o),e.drawLine(l[1],l[0],o),e.drawPoint(l[1],o),e.setFill("purple"),e.text("reflected",{x:l[1].x+10,y:l[1].y+3},o),e.setColor("rgb(200,200,255)"),e.drawLine(l[2],l[3],o),e.drawPoint(l[2],o),e.setColor("black"),e.setFill("black"),e.drawLine({x:t/2,y:n/2},{x:t/2+i-2,y:n/2},o),e.drawLine({x:t/2,y:n/2},{x:t/2,y:n/2+i-2},o),e.text("r = "+i,{x:t/2+i/3,y:n/2+10},o)},render:function(){return r.createElement("section",null,r.createElement(a,this.props),r.createElement("p",null,"In the previous section we tried to approximate a circular arc with a quadratic curve, and it mostly made us unhappy. Cubic curves are much better suited to this task, so what do we need to do?"),r.createElement("p",null,'For cubic curves, we basically want the curve to pass through three points on the circle: the start point, the mid point at "angle/2", and the end point at "angle". We then also need to make sure the control points are such that the start and end tangent lines line up with the circle\'s tangent lines at the start and end point.'),r.createElement("p",null,'The first thing we can do is "guess" what the curve should look like, based on the previously outlined curve-through-three-points procedure. This will give use a curve with correct start, mid and end points, but possibly incorrect derivatives at the start and end, because the control points might not be in the right spot. We can then slide the control points along the lines that connect them to their respective end point, until they effect the corrected derivative at the start and end points. However, if you look back at the section on fitting curves through three points, the rules used were such that they optimized for a near perfect hemisphere, so using the same guess won\'t be all that useful: guessing the solution based on knowing the solution is not really guessing.'),r.createElement("p",null,'So have a graphical look at a "bad" guess versus the true fit, where we\'ll be using the bad guess and the description in the second paragraph to derive the maths for the true fit:'),r.createElement(i,{preset:"arcfitting",title:"Cubic Bézier arc approximation",setup:this.setup,draw:this.draw,onMouseMove:this.onMouseMove}),r.createElement("p",null,'We see two curves here; in blue, our "guessed" curve and its control points, and in grey/black, the true curve fit, with proper control points that were shifted in, along line between our guessed control points, such that the derivatives at the start and end points are correct.'),r.createElement("p",null,'We can already seethat cubic curves are a lot better than quadratic curves, and don\'t look all that wrong until we go well past a quarter circle; ⅜th starts to hint at problems, and half a circle has an obvious "gap" between the real circle and the cubic approximation. Anything past that just looks plain ridiculous... but quarter curves actually look pretty okay!'),r.createElement("p",null,'So, maths time again: how okay is "okay"? Let\'s apply some more maths to find out.'),r.createElement("p",null,"Unlike for the quadratic curve, we can't use ",r.createElement("i",null,"t=0.5")," as our reference point because by its very nature it's one of the three points that are actually guaranteed to lie on the circular curve. Instead, we need a different ",r.createElement("i",null,"t")," value. If we run some analysis on the curve we find that the actual ",r.createElement("i",null,"t"),' value at which the curve is furthest from what it should be is 0.211325 (rounded), but we don\'t know "why", since finding this value involves root-finding, and is nearly impossible to do symbolically without pages and pages of math just to express one of the possible solutions.'),r.createElement("p",null,"So instead of walking you through the derivation for that value, let's simply take that ",r.createElement("i",null,"t")," value and see what the error is for circular arcs with an angle ranging from 0 to 2π:"),r.createElement("table",null,r.createElement("tbody",null,r.createElement("tr",null,r.createElement("td",null,r.createElement("p",null,r.createElement("img",{src:"images/arc-c-2pi.gif",height:"187px"})),r.createElement("p",null,"plotted for 0 ≤ φ ≤ 2π:")),r.createElement("td",null,r.createElement("p",null,r.createElement("img",{src:"images/arc-c-pi.gif",height:"187px"})),r.createElement("p",null,"plotted for 0 ≤ φ ≤ π:")),r.createElement("td",null,r.createElement("p",null,r.createElement("img",{src:"images/arc-c-pi2.gif",height:"187px"})),r.createElement("p",null,"plotted for 0 ≤ φ ≤ ½π:"))))),r.createElement("p",null,"We see that cubic Bézier curves are much better when it comes to approximating circular arcs, with an error of less than 0.027 at the two \"bulge\" points for a quarter circle (which had an error of 0.06 for quadratic curves at the mid point), and an error near 0.001 for an eighth of a circle, so we're getting less than half the error for a quarter circle, or: at a slightly lower error, we're getting twice the arc. This makes cubic curves quite useful!"),r.createElement("p",null,'In fact, the precision of a cubic curve at a quarter circle is considered "good enough" by so many people that it\'s generally considered "just fine" to use four cubic Bézier curves to fake a full circle when no circle primitives are available; generally, people won\'t notice that it\'s not a real circle unless you also happen to overlay an actual circle, so that the difference becomes obvious.'),r.createElement("p",null,'So with the error analysis out of the way, how do we actually compute the coordinates needed to get that "true fit" cubic curve? The first observation is that we already know the start and end points, because they\'re the same as for the quadratic attempt:'),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/ef34ab8f466ed3294895135a346b55ada05d779d.svg",style:{width:"13.275rem",height:"2.6248500000000003rem"}})),r.createElement("p",null,"But we now need to find two control points, rather than one. If we want the derivatives at the start and end point to match the circle, then the first control point can only lie somewhere on the vertical line through S, and the second control point can only lie somewhere on the line tangent to point E, which means:"),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/4df65dae78bc5a0e6c5f23a2faae9a9d7a8b39b3.svg",style:{width:"8.325000000000001rem",height:"2.55015rem"}})),r.createElement("p",null,'where "a" is some scaling factor, and:'),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/cb32f8f9c3ae2b264a48003c237a798d02dc8935.svg",style:{width:"11.62485rem",height:"2.6248500000000003rem"}})),r.createElement("p",null,'where "b" is also some scaling factor.'),r.createElement("p",null,"Starting with this information, we slowly maths our way to success, but I won't lie: the maths for this is pretty trig-heavy, and it's easy to get lost if you remember (or know!) some of the core trigonoetric identities, so if you just want to see the final result just skip past the next section!"),r.createElement("div",{className:"note"},r.createElement("h2",null,"Let's do this thing."),r.createElement("p",null,"Unlike for the quadratic case, we need some more information in order to compute ",r.createElement("i",null,"a")," and ",r.createElement("i",null,"b"),", since they're no longer dependent variables. First, we observe that the curve is symmetrical, so whatever values we end up finding for C",r.createElement("sub",null,"1")," will apply to C",r.createElement("sub",null,"2")," as well (rotated along its tangent), so we'll focus on finding the location of C",r.createElement("sub",null,"1")," only. So here's where we do something that you might not expect: we're going to ignore for a moment, because we're going to have a much easier time if we just solve this problem with geometry first, then move to calculus to solve a much simpler problem."),r.createElement("p",null,"If we look at the triangle that is formed between our starting point, or initial guess C",r.createElement("sub",null,"1"),"and our real C",r.createElement("sub",null,"1"),", there's something funny going on: if we treat the line ","{","start,guess","}"," as our opposite side, the line ","{","guess,real","}"," as our adjacent side, with ","{","start,real","}"," our hypothenuse, then the angle for the corner hypothenuse/adjacent is half that of the arc we're covering. Try it: if you place the end point at a quarter circle (pi/2, or 90 degrees), the angle in our triangle is half a quarter (pi/4, or 45 degrees). With that knowledge, and a knowledge of what the length of any of our lines segments are (as a function), we can determine where our control points are, and thus have everything we need to find the error distance function. Of the three lines, the one we can easiest determine is ","{","start,guess","}",", so let's find out what the guessed control point is. Again geometrically, because we have the benefit of an on-curve ",r.createElement("i",null,"t=0.5")," value."),r.createElement("p",null,"The distance from our guessed point to the start point is exactly the same as the projection distance we looked at earlier. Using ",r.createElement("i",null,"t=0.5"),' as our point "B" in the "A,B,C" projection, then we know the length of the line segment ',"{","C,A","}",", since it's d",r.createElement("sub",null,"1")," = ","{","A,B","}"," + d",r.createElement("sub",null,"2")," = ","{","B,C","}",":"),r.createElement("p",null,r.createElement("img",{ className:"LaTeX SVG",src:"images/latex/b15a274c1e0a6aeeaf517b5d2c8ee0a7997dd617.svg",style:{width:"27.675rem",height:"2.32515rem"}})),r.createElement("p",null,"So that just leaves us to find the distance from ",r.createElement("i",null,"t=0.5")," to the baseline for an arbitrary angle φ, which is the distance from the centre of the circle to our ",r.createElement("i",null,"t=0.5")," point, minus the distance from the centre to the line that runs from start point to end point. The first is the same as the point P we found for the quadratic curve:"),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0b80423188012451e0400f473c19729eb2bad654.svg",style:{width:"13.350150000000001rem",height:"2.025rem"}})),r.createElement("p",null,"And the distance from the origin to the line start/end is another application of angles, since the triangle ","{","origin,start,C","}"," has known angles, and two known sides. We can find the length of the line ","{","origin,C","}",", which lets us trivially compute the coordinate for C:"),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/9be55fb38d5d30bbc6c7140afb1c7bc097bc044e.svg",style:{width:"18.675rem",height:"5.3248500000000005rem"}})),r.createElement("p",null,"With the coordinate C, and knowledge of coordinate B, we can determine coordinate A, and get a vector that is identical to the vector ","{","start,guess","}",":"),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/262f2eca63105779f30a0a5445cf76f60786039a.svg",style:{width:"27.675rem",height:"3.67515rem"}})),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/0e83ebbac13a84ef6036bf4be57b3d1b6cb316f8.svg",style:{width:"14.99985rem",height:"3.29985rem"}})),r.createElement("p",null,"Which means we can now determine the distance ","{","start,guessed","}",", which is the same as the distance","{","C,A","}",", and use that to determine the vertical distance from our start point to our C",r.createElement("sub",null,"1"),":"),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c87e454fb11ef7f15c7386e83ca1ce41a004d8a7.svg",style:{width:"17.850150000000003rem",height:"4.64985rem"}})),r.createElement("p",null,"And after this tedious detour to find the coordinate for C",r.createElement("sub",null,"1"),", we can find C",r.createElement("sub",null,"2")," fairly simply, since it's lies at distance -C",r.createElement("sub",null,"1y")," along the end point's tangent:"),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/25f027074b6af8ca7b640e27636e3bf89c28afdb.svg",style:{width:"36.675000000000004rem",height:"6.89985rem"}})),r.createElement("p",null,"And that's it, we have all four points now for an approximation of an arbitrary circular arc with angle φ.")),r.createElement("p",null,"So, to recap, given an angle φ, the new control coordinates are:"),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/c4d82e44d1c67dda8ba26aa6da0f406d05eba618.svg",style:{width:"15.075000000000001rem",height:"2.55015rem"}})),r.createElement("p",null,"and"),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/3a4b1ee00eebb7697e5513ef9df673928913252e.svg",style:{width:"23.02515rem",height:"2.6248500000000003rem"}})),r.createElement("p",null,'And, because the "quarter curve" special case comes up so incredibly often, let\'s look at what these new control points mean for the curve coordinates of a quarter curve, by simply filling in φ = π/2:'),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/63e0936b4849d4cdbb9a2e0909181259be951e4d.svg",style:{width:"28.65015rem",height:"1.94985rem"}})),r.createElement("p",null,"Which, in decimal values, rounded to six significant digits, is:"),r.createElement("p",null,r.createElement("img",{className:"LaTeX SVG",src:"images/latex/fd12e65204a31319b66355c6ff99e6b3d9603b05.svg",style:{width:"28.65015rem",height:"1.125rem"}})),r.createElement("p",null,"Of course, this is for a circle with radius 1, so if you have a different radius circle, simply multiply the coordinate by the radius you need. And then finally, forming a full curve is now a simple a matter of mirroring these coordinates about the origin:"),r.createElement(i,{preset:"simple",title:"Cubic Bézier circle approximation",draw:this.drawCircle,"static":!0}))}});e.exports=u},function(e,t,n){"use strict";var r=n(2),i=n(215),a=n(223),o=n(226),s=Math.atan2,l=Math.PI,u=2*l,c=Math.cos,h=Math.sin,d=r.createClass({displayName:"Introduction",statics:{keyHandlingOptions:{propName:"error",values:{38:.1,40:-.1},controller:function(e){e.error<.1&&(e.error=.1)}}},getDefaultProps:function(){return{title:"Approximating Bézier curves with circular arcs"}},setupCircle:function(e){var t=new e.Bezier(70,70,140,40,240,130);e.setCurve(t)},setupQuadratic:function(e){var t=e.getDefaultQuadratic();e.setCurve(t)},setupCubic:function(e){var t=e.getDefaultCubic();e.setCurve(t),e.error=.5},getCCenter:function(e,t,n,r){var i,a=n.x-t.x,o=n.y-t.y,d=r.x-n.x,p=r.y-n.y,f=a*c(l/2)-o*h(l/2),m=a*h(l/2)+o*c(l/2),g=d*c(l/2)-p*h(l/2),v=d*h(l/2)+p*c(l/2),y=(t.x+n.x)/2,w=(t.y+n.y)/2,b=(n.x+r.x)/2,_=(n.y+r.y)/2,x=y+f,E=w+m,C=b+g,k=_+v,N=e.utils.lli8(y,w,x,E,b,_,C,k),S=e.utils.dist(N,t),P=s(t.y-N.y,t.x-N.x),D=s(n.y-N.y,n.x-N.x),O=s(r.y-N.y,r.x-N.x);return PD||D>O)&&(P+=u),P>O&&(i=O,O=P,P=i)):O s + L - order; i--) ","{","\n"," let numerator = t - knots[i]","\n"," let denominator = knots[i - L + order] - knots[i]","\n"," let alpha = numerator / denominator","\n"," let v[i] = alpha * v[i] + (1-alpha) * v[i-1]","\n"," ","}","\n"," ","}"),r.createElement("p",null,'(A nice bit of behaviour in this code is that we work the interpolation "backwards", starting at ',r.createElement("code",null,"i=s")," at each level of the interpolation, and we stop when ",r.createElement("code",null,"i = s - order + level"),", so we always end up with a value for ",r.createElement("code",null,"i")," such that those ",r.createElement("code",null,"v[i-1]")," don't try to use an array index that doesn't exist)"),r.createElement("h2",null,"Open vs. closed paths"),r.createElement("p",null,"Much like poly-Béziers, B-Splines can be either open, running from the first point to the last point, or closed, where the first and last point are ",r.createElement("em",null,"the same point"),". However, because B-Splines are an interpolation of curves, not just point, we can't simply make the first and last point the same, we need to link a few point point: for an order ",r.createElement("code",null,"d")," B-Spline, we need to make the last ",r.createElement("code",null,"d")," point the same as the first ",r.createElement("code",null,"d")," points. And the easiest way to do this is to simply append ",r.createElement("code",null,"points.splice(0,d)")," to ",r.createElement("code",null,"points"),". Done!"),r.createElement("p",null,'Of course if we want to manipulate these kind of curves we need to make sure to mark them as "closed" so that we know the coordinate for ',r.createElement("code",null,"points[0]")," and ",r.createElement("code",null,"points[n-k]")," etc. are the same coordinate, and manipulating one will equally manipulate the other, but programming generally makes this really easy by storing references to coordinates (or other linked values such as coordinate weights, discussed in the NURBS section) rather than separate coordinate objects."),r.createElement("h2",null,"Manipulating the curve through the knot vector"),r.createElement("p",null,"The most important thing to understand when it comes to B-Splines is that they work ",r.createElement("em",null,"because"),' of the concept of a knot vector. As mentioned above, knots represent "where individual control points start/stop influencing the curve", but we never looked at the ',r.createElement("em",null,"values")," that go in the knot vector. If you look back at the N() and a() functions, you see that interpolations are based on intervals in the knot vector, rather than the actual values in the knot vector, and we can exploit this to do some pretty interesting things with clever manipulation of the knot vector. Specifically there are four things we can do that are worth looking at:"),r.createElement("ol",null,r.createElement("li",null,"we can use a uniform knot vector, with equally spaced intervals,"),r.createElement("li",null,"we can use a non-uniform knot vector, without enforcing equally spaced internvals,"),r.createElement("li",null,'we can collapse sequential knots to the same value, locally lowering curve complexity using "null" intervals, and'),r.createElement("li",null,"we can form a special case non-uniform vector, by combining (1) and (3) to for a vector with collapsed start and end knots, with a uniform vector in between.")),r.createElement("h3",null,"Uniform B-Splines"),r.createElement("p",null,"The most straightforward type of B-Spline is the uniform spline. In a uniform spline, the knots are distributed uniformly over the entire curve interval. For instance, if we have a knot vector of length twelve, then a uniform knot vector would be [0,1,2,3,...,9,10,11]. Or [4,5,6,...,13,14,15], which defines ",r.createElement("em",null,"the same intervals"),", or even [0,2,3,...,18,20,22], which also defines ",r.createElement("em",null,"the same intervals"),", just scaled by a constant factor, which becomes normalised during interpolation and so does not contribute to the curvature."),r.createElement("div",{ -className:"two-column"},r.createElement(o,{ref:"uniform-spline"}),r.createElement(i,{sketch:n(270),controller:function(t,n){return e.bindKnots(t,n,"uniform-spline")}})),r.createElement("p",null,"This is an important point: the intervals that the knot vector defines are ",r.createElement("em",null,"relative")," intervals, so it doesn't matter if every interval is size 1, or size 100 - the relative differences between the intervals is what shapes any particular curve."),r.createElement("p",null,"The problem with uniform knot vectors is that, as we need ",r.createElement("code",null,"order"),' control points before we have any curve with which we can perform interpolation, the curve does not "start" at the first point, nor "ends" at the last point. Instead there are "gaps". We can get rid of these, by being clever about how we apply the following uniformity-breaking approach instead...'),r.createElement("h3",null,"Reducing local curve complexity by collapsing intervals"),r.createElement("p",null,"By collapsing knot intervals by making two or more consecutive knots have the same value, we can reduce the curve complexity in the sections that are affected by the knots involved. This can have drastic effects: for ever interval collapse, the curve order goes down, and curve continuity goes down, to the point where collapsing ",r.createElement("code",null,"order"),' knots creates a situation where all continuity is lost and the curve "kinks".'),r.createElement("div",{className:"two-column"},r.createElement(o,{ref:"center-cut-bspline"}),r.createElement(i,{sketch:n(271),controller:function(t,n){return e.bindKnots(t,n,"center-cut-bspline")}})),r.createElement("h3",null,"Open-Uniform B-Splines"),r.createElement("p",null,"By combining knot interval collapsing at the start and end of the curve, with uniform knots in between, we can overcome the problem of the curve not starting and ending where we'd kind of like it to:"),r.createElement("p",null,"For any curve of degree ",r.createElement("code",null,"D")," with control points ",r.createElement("code",null,"N"),", we can define a knot vector of length ",r.createElement("code",null,"N+D+1")," in which the values ",r.createElement("code",null,"0 ... D+1")," are the same, the values ",r.createElement("code",null,"D+1 ... N+1"),' follow the "uniform" pattern, and the values ',r.createElement("code",null,"N+1 ... N+D+1"),' are the same again. For example, a cubic B-Spline with 7 control points can have a knot vector [0,0,0,0,1,2,3,4,4,4,4], or it might have the "identical" knot vector [0,0,0,0,2,4,6,8,8,8,8], etc. Again, it is the relative differences that determine the curve shape.'),r.createElement("div",{className:"two-column"},r.createElement(o,{ref:"open-uniform-bspline"}),r.createElement(i,{sketch:n(272),controller:function(t,n){return e.bindKnots(t,n,"open-uniform-bspline")}})),r.createElement("h3",null,"Non-uniform B-Splines"),r.createElement("p",null,'This is essentialy the "free form" version of a B-Spline, and also the least interesting to look at, as without any specific reason to pick specific knot intervals, there is nothing particularly interesting going on. There is one constraint to the knot vector, and that is that any value ',r.createElement("code",null,"knots[k+1]"),"should be equal to, or greater than ",r.createElement("code",null,"knots[k]"),"."),r.createElement("h2",null,"One last thing: Rational B-Splines"),r.createElement("p",null,'While it is true that this section on B-Splines is running quite long already, there is one more thing we need to talk about, and that\'s "Rational" splines, where the rationality applies to the "ratio", or relative weights, of the control points themselves. By introducing a ratio vector with weights to apply to each control point, we greatly increase our influence over the final curve shape: the more weight a control point carries, the close to that point the spline curve will lie, a bit like turning up the gravity of a control point.'),r.createElement("div",{className:"two-column"},r.createElement(s,{ref:"rational-uniform-bspline-weights"}),r.createElement(i,{scrolling:!0,sketch:n(273),controller:function(t,n,r,i){e.bindWeights(t,r,i,"rational-uniform-bspline-weights")}})),r.createElement("p",null,'Of course this brings us to the final topic that any text on B-Splines must touch on before calling it a day: the NURBS, or Non-Uniform Rational B-Spline (NURBS is not a plural, the capital S actually just stands for "spline", but a lot of people mistakenly treat it as if it is, so now you know better). NURBS are an important type of curve in computer-facilitated design, used a lot in 3D modelling (as NURBS surfaces) as well as in arbitrary-precision 2D design due to the level of control a NURBS curve offers designers.'),r.createElement("p",null,"While a true non-uniform rational B-Spline would be hard to work with, when we talk about NURBS we typically mean the Open-Uniform Rational B-Spline, or OURBS, but that doesn't roll off the tongue nearly as nicely, and so remember that when people talk about NURBS, they typically mean open-uniform, which has the useful property of starting the curve at the first control point, and ending it at the last."),r.createElement("h2",null,"Extending our implementation to cover rational splines"),r.createElement("p",null,"The algorithm for working with Rational B-Splines is virtually identical to the regular algorithm, and the extension to work in the control point weights is fairly simple: we extend each control point from a point in its original number of dimensions (2D, 3D, etc) to one dimension higher, scaling the original dimensions by the control point's weight, and then assigning that weight as its value for the extended dimension."),r.createElement("p",null,"For example, a 2D point ",r.createElement("code",null,"(x,y)")," with weight ",r.createElement("code",null,"w")," becomes a 3D point ",r.createElement("code",null,"(w * x, w * y, w)"),"."),r.createElement("p",null,"We then run the same algorithm as before, which will automaticall perform weight interpolation in addition to regular coordinate interpolation, because all we've done is pretended we have coordinates in a higher dimension. The algorithm doesn't really care about how many dimensions it needs to interpolate."),r.createElement("p",null,'In order to recover our "real" curve point, we take the final result of the point generation algorithm, and "unweigh" it: we take the final point\'s derived weight ',r.createElement("code",null,"w'")," and divide all the regular coordinate dimensions by it, then throw away the weight information."),r.createElement("p",null,"Based on our previous example, we take the final 3D point ",r.createElement("code",null,"(x', y', w')"),", which we then turn back into a 2D point by computing ",r.createElement("code",null,"(x'/w', y'/w')"),". And that's it, we're done!"))}});e.exports=l},function(e,t,n){"use strict";var r=n(2),i=n(265),a=r.createClass({displayName:"BSplineGraphic",componentWillMount:function(){var e=this;this.cvs=void 0,this.ctx=void 0,this.key=void 0,this.keyCode=void 0,this.mouseX=void 0,this.mouseY=void 0,this.isMouseDown=void 0,this.width=0,this.height=0,this.activeDistance=9,this.points=[],this.knots=[],this.weights=[],this.nodes=[],this.cp=void 0,this.dx=void 0,this.dy=void 0;var t=this.props.sketch;Object.keys(t).forEach(function(n){e[n]=t[n],"function"==typeof e[n]&&(e[n]=e[n].bind(e))})},render:function(){return r.createElement("canvas",{className:"bspline-graphic",ref:"sketch"})},keydownlisten:function(e){this.setKeyboardValues(e),this.keyDown()},keyuplisten:function(e){this.setKeyboardValues(e),this.keyUp()},keypresslisten:function(e){this.setKeyboardValues(e),this.keyPressed()},mousedownlisten:function(e){this.setMouseValues(e),this.mouseDown()},mouseuplisten:function(e){this.setMouseValues(e),this.mouseUp()},mousemovelisten:function(e){this.setMouseValues(e),this.mouseMove(),this.isMouseDown&&this.mouseDrag&&this.mouseDrag()},wheellissten:function(e){e.preventDefault(),this.scrolled(e.deltaY<0?1:-1)},componentDidMount:function(){var e=this.cvs=this.refs.sketch;e.addEventListener("keydown",this.keydownlisten),e.addEventListener("keyup",this.keyuplisten),e.addEventListener("keypress",this.keypresslisten),e.addEventListener("mousedown",this.mousedownlisten),e.addEventListener("mouseup",this.mouseuplisten),e.addEventListener("mousemove",this.mousemovelisten),this.props.scrolling&&e.addEventListener("wheel",this.wheellissten),this.setup()},componentWillUnmount:function(){var e=this.cvs=this.refs.sketch;e.removeEventListener("keydown",this.keydownlisten),e.removeEventListener("keyup",this.keyuplisten),e.removeEventListener("keypress",this.keypresslisten),e.removeEventListener("mousedown",this.mousedownlisten),e.removeEventListener("mouseup",this.mouseuplisten),e.removeEventListener("mousemove",this.mousemovelisten),this.props.scrolling&&e.removeEventListener("wheel",this.wheellissten)},drawCurve:function(e){e=e||this.points;var t=this.ctx,n=this.weights.length>0&&this.weights;t.beginPath();var r=i(0,this.degree,e,this.knots,n);t.moveTo(r[0],r[1]);for(var a=.01;a<1;a+=.01)r=i(a,this.degree,e,this.knots,n),t.lineTo(r[0],r[1]);r=i(1,this.degree,e,this.knots,n),t.lineTo(r[0],r[1]),t.stroke(),t.closePath()},drawKnots:function(e){var t=this,n=this.knots,r=this.weights.length>0&&this.weights;n.forEach(function(a,o){if(!(on.length-1-t.degree)){var s=i(a,t.degree,e,n,r,!1,!0);t.circle(s[0],s[1],3)}})},drawNodes:function(e){var t,n=this;this.stroke(150),this.nodes.forEach(function(r,a){try{t=i(r,n.degree,e,n.knots,!1,!1,!0),n.line(t[0],t[1],e[a][0],e[a++][1])}catch(o){console.error(o)}})},formKnots:function(e,t){if(t=t===!0,!t)return this.formUniformKnots(e);var n,r=e.length,i=[],a=r-this.degree;for(n=1;n=0;n--)t.push(n);return t.reverse()},formNodes:function(e,t){var n,r,i,a=[this.degree,e.length-1-this.degree],o=[];for(r=0;re[a[1]]||o.push(n)}return o},formWeights:function(e){var t=[];return e.forEach(function(e){return t.push(1)}),t},setDegree:function(e){this.degree+=e,this.knots=this.formKnots(this.points),this.nodes=this.formNodes(this.knots,this.points)},near:function(e,t,n){var r=e.x-t,i=e.y-n,a=Math.sqrt(r*r+i*i);return a1&&this.setDegree(-1),this.redraw()},keyUp:function(){},keyPressed:function(){},mouseDown:function(){this.isMouseDown=!0,this.cp=this.getCurrentPoint(this.mouseX,this.mouseY),this.cp||(this.points.push({x:this.mouseX,y:this.mouseY}),this.knots=this.formKnots(this.points),this.nodes=this.formNodes(this.knots,this.points)),this.redraw()},mouseUp:function(){this.isMouseDown=!1,this.cp=!1,this.redraw()},mouseDrag:function(){this.cp&&(this.cp.x=this.mouseX,this.cp.y=this.mouseY,this.redraw())},mouseMove:function(){},scrolled:function(e){if(this.cp=this.getCurrentPoint(this.mouseX,this.mouseY),this.cp){var t=this.points.indexOf(this.cp);this.weights.length>t&&(this.weights[t]+=.1*e,this.weights[t]<0&&(this.weights[t]=0)),t=this.points.indexOf(this.cp,t+1),t!==-1&&this.weights.length>t&&(this.weights[t]+=.1*e,this.weights[t]<0&&(this.weights[t]=0)),this.redraw()}},setKeyboardValues:function(e){e.ctrlKey||e.metaKey||e.altKey||e.preventDefault(),this.key=e.key,this.keyCode=e.code},setMouseValues:function(e){var t=this.cvs.getBoundingClientRect();this.mouseX=e.clientX-t.left,this.mouseY=e.clientY-t.top},size:function(e,t){this.width=0|e,this.height=0|(t||e),this.cvs.width=this.width,this.cvs.height=this.height,this.ctx=this.cvs.getContext("2d")},redraw:function(){this.draw()},clear:function(){this.ctx.clearRect(0,0,this.width,this.height)},grid:function(e){e=(0|(e||10))+.5,this.stroke(200,200,220);for(var t=e;th-1)throw new Error("degree must be less than or equal to point count - 1");if(!i)for(i=[],s=0;sm)throw new Error("out of bounds");for(u=p[0];u=r[u]&&e<=r[u+1]);u++);var g=[];for(s=0;su-t-1+c;s--)for(v=(e-r[s])/(r[s+t+1-c]-r[s]),l=0;l=s)return null;var c={type:t,min:n,max:i,step:a,value:l,onChange:function(t){var n=e.state.weights;n[u]=t.target.value,o&&u0&&this.weights;t.beginPath();var r=i(0,this.degree,e,this.knots,n);t.moveTo(r[0],r[1]);for(var a=.01;a<1;a+=.01)r=i(a,this.degree,e,this.knots,n),t.lineTo(r[0],r[1]);r=i(1,this.degree,e,this.knots,n),t.lineTo(r[0],r[1]),t.stroke(),t.closePath()},drawKnots:function(e){var t=this,n=this.knots,r=this.weights.length>0&&this.weights;n.forEach(function(a,o){if(!(on.length-1-t.degree)){var s=i(a,t.degree,e,n,r,!1,!0);t.circle(s[0],s[1],3)}})},drawNodes:function(e){var t,n=this;this.stroke(150),this.nodes.forEach(function(r,a){try{t=i(r,n.degree,e,n.knots,!1,!1,!0),n.line(t[0],t[1],e[a][0],e[a++][1])}catch(o){console.error(o)}})},formKnots:function(e,t){if(t=t===!0,!t)return this.formUniformKnots(e);var n,r=e.length,i=[],a=r-this.degree;for(n=1;n=0;n--)t.push(n);return t.reverse()},formNodes:function(e,t){var n,r,i,a=[this.degree,e.length-1-this.degree],o=[];for(r=0;re[a[1]]||o.push(n)}return o},formWeights:function(e){var t=[];return e.forEach(function(e){return t.push(1)}),t},setDegree:function(e){this.degree+=e,this.knots=this.formKnots(this.points),this.nodes=this.formNodes(this.knots,this.points)},near:function(e,t,n){var r=e.x-t,i=e.y-n,a=Math.sqrt(r*r+i*i);return a1&&this.setDegree(-1),this.redraw()},keyUp:function(){},keyPressed:function(){},mouseDown:function(){this.isMouseDown=!0,this.cp=this.getCurrentPoint(this.mouseX,this.mouseY),this.cp||(this.points.push({x:this.mouseX,y:this.mouseY}),this.knots=this.formKnots(this.points),this.nodes=this.formNodes(this.knots,this.points)),this.redraw()},mouseUp:function(){this.isMouseDown=!1,this.cp=!1,this.redraw()},mouseDrag:function(){this.cp&&(this.cp.x=this.mouseX,this.cp.y=this.mouseY,this.redraw())},mouseMove:function(){},scrolled:function(e){if(this.cp=this.getCurrentPoint(this.mouseX,this.mouseY),this.cp){var t=this.points.indexOf(this.cp);this.weights.length>t&&(this.weights[t]+=.1*e,this.weights[t]<0&&(this.weights[t]=0)),t=this.points.indexOf(this.cp,t+1),t!==-1&&this.weights.length>t&&(this.weights[t]+=.1*e,this.weights[t]<0&&(this.weights[t]=0)),this.redraw()}},setKeyboardValues:function(e){e.ctrlKey||e.metaKey||e.altKey||e.preventDefault(),this.key=e.key,this.keyCode=e.code},setMouseValues:function(e){var t=this.cvs.getBoundingClientRect();this.mouseX=e.clientX-t.left,this.mouseY=e.clientY-t.top},size:function(e,t){this.width=0|e,this.height=0|(t||e),this.cvs.width=this.width,this.cvs.height=this.height,this.ctx=this.cvs.getContext("2d")},redraw:function(){this.draw()},clear:function(){this.ctx.clearRect(0,0,this.width,this.height)},grid:function(e){e=(0|(e||10))+.5,this.stroke(200,200,220);for(var t=e;th-1)throw new Error("degree must be less than or equal to point count - 1");if(!i)for(i=[],s=0;sm)throw new Error("out of bounds");for(u=p[0];u=r[u]&&e<=r[u+1]);u++);var g=[];for(s=0;su-t-1+c;s--)for(v=(e-r[s])/(r[s+t+1-c]-r[s]),l=0;l=s)return null;var c={type:t,min:n,max:i,step:a,value:l,onChange:function(t){var n=e.state.weights;n[u]=t.target.value,o&&uQuestions, comments: - If you have suggestions for new sections, hit up the github +

If you have suggestions for new sections, hit up the github issue tracker (also reachable from the repo linked to in the upper right). If you have questions about the material, there's currently no comment section while I'm doing the rewrite, but you can use the issue tracker for that as well. Once the rewrite is done, I'll add a general comment section back in, and maybe a more topical "select this section of text and hit the - 'question' button to ask a question about it" system. We'll see. + 'question' button to ask a question about it" system. We'll see.

Buy me a coffee?

- +

If you enjoyed this book, or you simply found it useful for something you were trying to get done, and you were wondering how to let me know you appreciated this book, you can always - + );