| 
														
															@@ -20,6 +20,34 @@ const LOCAL_STORAGE_KEY_STATE = "excalidraw-state"; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 const elements = Array.of<ExcalidrawElement>(); 
														 | 
														
														 | 
														
															 const elements = Array.of<ExcalidrawElement>(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+let skipHistory = false; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+const stateHistory: string[] = []; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+function generateHistoryCurrentEntry() { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  return JSON.stringify( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    elements.map(element => ({ ...element, isSelected: false })) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  ); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+function pushHistoryEntry(newEntry: string) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  if ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    stateHistory.length > 0 && 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    stateHistory[stateHistory.length - 1] === newEntry 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  ) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    // If the last entry is the same as this one, ignore it 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    return; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  stateHistory.push(newEntry); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+function restoreHistoryEntry(entry: string) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  const newElements = JSON.parse(entry); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  elements.splice(0, elements.length); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  newElements.forEach((newElement: ExcalidrawElement) => { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    generateDraw(newElement); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    elements.push(newElement); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  }); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  // When restoring, we shouldn't add an history entry otherwise we'll be stuck with it and can't go back 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+  skipHistory = true; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 // https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript/47593316#47593316 
														 | 
														
														 | 
														
															 // https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript/47593316#47593316 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 const LCG = (seed: number) => () => 
														 | 
														
														 | 
														
															 const LCG = (seed: number) => () => 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   ((2 ** 31 - 1) & (seed = Math.imul(48271, seed))) / 2 ** 31; 
														 | 
														
														 | 
														
															   ((2 ** 31 - 1) & (seed = Math.imul(48271, seed))) / 2 ** 31; 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -901,6 +929,17 @@ class App extends React.Component<{}, AppState> { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       event.preventDefault(); 
														 | 
														
														 | 
														
															       event.preventDefault(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } else if (shapesShortcutKeys.includes(event.key.toLowerCase())) { 
														 | 
														
														 | 
														
															     } else if (shapesShortcutKeys.includes(event.key.toLowerCase())) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       this.setState({ elementType: findElementByKey(event.key) }); 
														 | 
														
														 | 
														
															       this.setState({ elementType: findElementByKey(event.key) }); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } else if (event.metaKey && event.code === "KeyZ") { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      let lastEntry = stateHistory.pop(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      // If nothing was changed since last, take the previous one 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      if (generateHistoryCurrentEntry() === lastEntry) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        lastEntry = stateHistory.pop(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      if (lastEntry !== undefined) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        restoreHistoryEntry(lastEntry); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      this.forceUpdate(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      event.preventDefault(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     } 
														 | 
														
														 | 
														
															     } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   }; 
														 | 
														
														 | 
														
															   }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1301,6 +1340,8 @@ class App extends React.Component<{}, AppState> { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                   }); 
														 | 
														
														 | 
														
															                   }); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                   lastX = x; 
														 | 
														
														 | 
														
															                   lastX = x; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                   lastY = y; 
														 | 
														
														 | 
														
															                   lastY = y; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                  // We don't want to save history when resizing an element 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                  skipHistory = true; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                   this.forceUpdate(); 
														 | 
														
														 | 
														
															                   this.forceUpdate(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                   return; 
														 | 
														
														 | 
														
															                   return; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                 } 
														 | 
														
														 | 
														
															                 } 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1319,6 +1360,8 @@ class App extends React.Component<{}, AppState> { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                   }); 
														 | 
														
														 | 
														
															                   }); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                   lastX = x; 
														 | 
														
														 | 
														
															                   lastX = x; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                   lastY = y; 
														 | 
														
														 | 
														
															                   lastY = y; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                  // We don't want to save history when dragging an element to initially size it 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+                  skipHistory = true; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                   this.forceUpdate(); 
														 | 
														
														 | 
														
															                   this.forceUpdate(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                   return; 
														 | 
														
														 | 
														
															                   return; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                 } 
														 | 
														
														 | 
														
															                 } 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1347,6 +1390,8 @@ class App extends React.Component<{}, AppState> { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															               if (this.state.elementType === "selection") { 
														 | 
														
														 | 
														
															               if (this.state.elementType === "selection") { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															                 setSelection(draggingElement); 
														 | 
														
														 | 
														
															                 setSelection(draggingElement); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															               } 
														 | 
														
														 | 
														
															               } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+              // We don't want to save history when moving an element 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+              skipHistory = true; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															               this.forceUpdate(); 
														 | 
														
														 | 
														
															               this.forceUpdate(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             }; 
														 | 
														
														 | 
														
															             }; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1384,6 +1429,8 @@ class App extends React.Component<{}, AppState> { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             window.addEventListener("mousemove", onMouseMove); 
														 | 
														
														 | 
														
															             window.addEventListener("mousemove", onMouseMove); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             window.addEventListener("mouseup", onMouseUp); 
														 | 
														
														 | 
														
															             window.addEventListener("mouseup", onMouseUp); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            // We don't want to save history on mouseDown, only on mouseUp when it's fully configured 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            skipHistory = true; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             this.forceUpdate(); 
														 | 
														
														 | 
														
															             this.forceUpdate(); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															           }} 
														 | 
														
														 | 
														
															           }} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         /> 
														 | 
														
														 | 
														
															         /> 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -1407,6 +1454,10 @@ class App extends React.Component<{}, AppState> { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															       viewBackgroundColor: this.state.viewBackgroundColor 
														 | 
														
														 | 
														
															       viewBackgroundColor: this.state.viewBackgroundColor 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     }); 
														 | 
														
														 | 
														
															     }); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     save(this.state); 
														 | 
														
														 | 
														
															     save(this.state); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    if (!skipHistory) { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+      pushHistoryEntry(generateHistoryCurrentEntry()); 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    skipHistory = false; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   } 
														 | 
														
														 | 
														
															   } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } 
														 | 
														
														 | 
														
															 } 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 |