EtherCalc for F2F

6,189 views

Published on

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
6,189
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
20
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

EtherCalc for F2F

  1. 1. EtherCalcMultiplayerSpreadsheetethercalc.net
  2. 2. Installation‣ npm install -g ethercalc‣ ethercalc Please connect to: http://0:8000/ ethercalc.org
  3. 3. aosabook.org
  4. 4. History
  5. 5. VisiCalc, 1979Dan Bricklin
  6. 6. Harvard, 1977
  7. 7. Harvard, 1977
  8. 8. Harvard, 1977
  9. 9. Harvard, 1977
  10. 10. Harvard, 1977
  11. 11. Original Vision
  12. 12. Original Vision Alto Workstation
  13. 13. Original Vision AltoCalculator- Workstation Mouse
  14. 14. Original Vision AltoCalculator- Workstation Head-mounted Mouse Display
  15. 15. Original Vision AltoCalculator- Workstation Head-mounted Mouse Display
  16. 16. =SUM( ) 0
  17. 17. 10 =SUM( ) 10 0
  18. 18. 10 20 =SUM( ) 30 10 0
  19. 19. 10 20 30 =SUM( ) 60 30 10 0
  20. 20. 10 20 30 =SUM( ) 60 30 10 0
  21. 21. 1977 → 1978
  22. 22. 1977 → 1978
  23. 23. 1977 → 1978 + Integer BASIC
  24. 24. 1978 → 1979
  25. 25. 1978 → 1979 10 20 30 =SUM( ) 60
  26. 26. 1978 → 1979 A B C D1 10 20 302 =SUM( ) 60
  27. 27. 1978 → 1979 A B C D1 10 20 302 =SUM(A1,B1,C1) 60
  28. 28. 1978 → 1979 A B C D1 10 20 302 =SUM(A1,B1,C1) 60 Bob & Dan
  29. 29. 1978 → 1979 A B C D 1 10 20 30 2 =SUM(A1,B1,C1) 60‣ Dan prototypes in BASIC Bob & Dan
  30. 30. 1978 → 1979 A B C D 1 10 20 30 2 =SUM(A1,B1,C1) 60‣ Dan prototypes in BASIC‣ Bob codes in 6502 ASM Bob & Dan
  31. 31. 1978 → 1979 A B C D 1 10 20 30 2 =SUM(A1,B1,C1) 60‣ Dan prototypes in BASIC‣ Bob codes in 6502 ASM‣ 700,000 copies in 6 years Bob & Dan
  32. 32. 1978 → 1979 A B C D 1 10 20 30 2 =SUM(A1,B1,C1) 60‣ Dan prototypes in BASIC‣ Bob codes in 6502 ASM‣ 700,000 copies in 6 years‣ The !rst “Killer App” Bob & Dan
  33. 33. 1981
  34. 34. 20 years passed
  35. 35. 20 years passed
  36. 36. 20 years passed
  37. 37. 20 years passed
  38. 38. 20 years passedNothing changed
  39. 39. “Can’t open”
  40. 40. “Can’t open”“MøjîbÃké”
  41. 41. “Can’t open”“MøjîbÃk锓Virus!”
  42. 42. Wikipedia, 2001
  43. 43. Wikipedia, 2001
  44. 44. Wikipedia, 2001
  45. 45. wikiCalc, 2005
  46. 46. wikiCalc, 2005✓ Plain text, HTML & Wiki syntax
  47. 47. wikiCalc, 2005✓ Plain text, HTML & Wiki syntax✓ References cells on other hosts
  48. 48. wikiCalc, 2005✓ Plain text, HTML & Wiki syntax✓ References cells on other hosts✓ Keeps all operations for auditing
  49. 49. wikiCalc, 2005✓ Plain text, HTML & Wiki syntax✓ References cells on other hosts✓ Keeps all operations for auditing✓ Revert to any revision
  50. 50. wikiCalc, 2005✓ Plain text, HTML & Wiki syntax✓ References cells on other hosts✓ Keeps all operations for auditing✓ Revert to any revision✓ Open Source! (GPLv2)
  51. 51. wikiCalc.pl
  52. 52. wikiCalc.pl 網站 Sites./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz
  53. 53. wikiCalc.pl 網站 Sites 頁面 Pages./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ
  54. 54. wikiCalc.pl 網站 Sites 頁面 Pages./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ Cells 儲存格
  55. 55. wikiCalc.pl 網站 Sites 頁面 Pages./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ Cells 儲存格 A1: 100
  56. 56. wikiCalc.pl 網站 Sites 頁面 Pages./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ Cells 儲存格 A1: 100 A2: =A1*2
  57. 57. wikiCalc.pl 網站 Sites 頁面 Pages./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ Cells 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2
  58. 58. wikiCalc.pl 網站 Sites 頁面 Pages./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ Cells 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2
  59. 59. wikiCalc.pl 網站 Sites 頁面 Pages./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ Cells 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2 B2: =YYY!D2
  60. 60. wikiCalc.pl 網站 Sites 頁面 Pages./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ Cells 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2 B2: =YYY!D2
  61. 61. wikiCalc.pl 網站 Sites 頁面 Pages./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ Cells 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2 B2: =YYY!D2 Cross-page Reference
  62. 62. wikiCalc Edit Flow
  63. 63. wikiCalc Edit Flow A1: 100 A2: =A1*2
  64. 64. wikiCalc Edit Flow A1: 100 A2: =A1*2
  65. 65. wikiCalc Edit Flow A1: 100 A2: =A1*2 POST / ajaxsetcell=host:page:A1:300 wikicalc.pl
  66. 66. wikiCalc Edit Flow A1: 100 A2: =A1*2 POST / ajaxsetcell=host:page:A1:300 wikicalc.pl 200 OK <?xml version="1.0"?> <root><![CDATA[ A1:v:300:300:right:1:1:: A2:f:600:A1*2:right:1:1:: ]]></root>
  67. 67. “Loading…”
  68. 68. “Loading…”
  69. 69. “Loading…”“C100k” Problem
  70. 70. “Loading…”“C100k” Problem
  71. 71. Undo
  72. 72. UndoRedo
  73. 73. SocialCalc, 2006Dan Bricklin Ross Mayfield
  74. 74. Design Goals
  75. 75. Design Goals‣ Rewrite calc engine in JS
  76. 76. Design Goals‣ Rewrite calc engine in JS‣ Real-time responsive editor
  77. 77. Design Goals‣ Rewrite calc engine in JS‣ Real-time responsive editor‣ Supports 100,000+ cells
  78. 78. Design Goals‣ Rewrite calc engine in JS‣ Real-time responsive editor‣ Supports 100,000+ cells‣ Works on all browsers (IE6+)
  79. 79. Design Goals‣ Rewrite calc engine in JS‣ Real-time responsive editor‣ Supports 100,000+ cells‣ Works on all browsers (IE6+)‣ Client-side log & undo/redo
  80. 80. Architecture
  81. 81. ArchitectureSocialCalc.jsHTTP Server
  82. 82. Architecture SocialCalc.jsGET HTTP Server
  83. 83. Architecture SocialCalc.jsGET HTTP Server
  84. 84. Architecture SocialCalc.jsGET GET HTTP Server
  85. 85. Architecture SocialCalc.jsGET GET ($) HTTP Server
  86. 86. Architecture SocialCalc.js PUTGET GET ($) HTTP Server
  87. 87. Architecture SocialCalc.js PUTGET GET ($) HTTP Server
  88. 88. Command Pattern
  89. 89. Command Patternset A1 value n 42
  90. 90. Command Patternset A1 value n 42set A2 formula A1*2
  91. 91. Command Patternset A1 value n 42set A2 formula A1*2merge A1:B2cut A3paste A4sort A1:B9 A up B downset sheet defaultcolor blue...
  92. 92. Command Pattern set A1 value n 42 set A2 formula A1*2‣ Async recalc loop
  93. 93. Command Pattern set A1 value n 42 set A2 formula A1*2‣ Async recalc loop‣ Visible-only redraw
  94. 94. Command Pattern set A1 value n 42 set A2 formula A1*2‣ Async recalc loop‣ Visible-only redraw‣ Unlimited undo/redo
  95. 95. Command Pattern set A1 value n 42 set A2 formula A1*2‣ Async recalc loop‣ Visible-only redraw‣ Unlimited undo/redo‣ UI stays responsive
  96. 96. Command Pattern set A1 value n 42 set A2 formula A1*2‣ Async recalc loop‣ Visible-only redraw‣ Unlimited undo/redo‣ UI stays responsive
  97. 97. “Social”Calc
  98. 98. “Social”Calc
  99. 99. “Social”Calc Signal, Like, Tag, Share, Embed...
  100. 100. Objects Relations
  101. 101. Objects Relations
  102. 102. Objects Relations
  103. 103. Good !rstPro!ts later
  104. 104. Common PublicAttribution License
  105. 105. Common Public Attribution License ⓐBSD, MIT
  106. 106. Common Public Attribution License © ⓐBSD, MIT LGPL, MPL
  107. 107. Common Public Attribution License © ++© ⓐBSD, MIT LGPL, MPL GPL
  108. 108. Common Public Attribution License © ++© ⓐBSD, MIT LGPL, MPL GPL “ASP
  109. 109.  loophole”
  110. 110. Common Public Attribution License © ++© ⓐBSD, MIT LGPL, MPL GPL “ASP
  111. 111.  loophole” Affero GPL
  112. 112. Common Public Attribution License © ++© ⓐBSD, MIT LGPL, MPL GPL “ASP
  113. 113.  loophole” CPAL Affero GPL
  114. 114. Common Public Attribution License © ++© ⓐBSD, MIT LGPL, MPL GPL “ASP
  115. 115.  loophole” CPAL Affero GPL
  116. 116. Common Public Attribution License © ++© ⓐBSD, MIT LGPL, MPL GPL “ASP
  117. 117.  loophole” CPAL Affero GPL
  118. 118. Common Public Attribution License © ++© ⓐBSD, MIT LGPL, MPL GPL “ASP
  119. 119.  loophole” CPAL Affero GPL
  120. 120. Sheetnode, 2008Karim Ratib
  121. 121. Sheetnode, 2008 Views + Fields + CCKKarim Ratib
  122. 122. Sheetnode, 2008 Views + Fields + CCK SocialCalc.jsKarim Ratib
  123. 123. Sheetnode, 2008 Views + Fields + CCK SocialCalc.jsKarim Ratib
  124. 124. Sheetnode, 2008 Views + Fields + CCK SocialCalc.jsKarim Ratib
  125. 125. Sheetnode, 2008 Views + Fields + CCK SocialCalc.jsKarim Ratib
  126. 126. OLPC, 2008
  127. 127. OLPC, 2008Luke Closs Dan
  128. 128. MeshP2P
  129. 129. Manusheel GuptaVijit Singh
  130. 130. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js XoCom.pyManusheel GuptaVijit Singh
  131. 131. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.pyManusheel GuptaVijit Singh
  132. 132. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.py D-Bus + TelepathyManusheel GuptaVijit Singh
  133. 133. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.py D-Bus + Telepathy OLPC MeshManusheel Gupta Broadcast 網絡廣播Vijit Singh
  134. 134. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.py D-Bus + Telepathy OLPC MeshManusheel Gupta Broadcast 網絡廣播 D-Bus + Telepathy Gecko/XPCOM SocialCalc.js XoCom.js XoCom.pyVijit Singh SocialCalcActivity.py
  135. 135. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.py D-Bus + Telepathy OLPC MeshManusheel Gupta Broadcast 網絡廣播 D-Bus + Telepathy Gecko/XPCOM set A1 value n 42 SocialCalc.js XoCom.js XoCom.pyVijit Singh SocialCalcActivity.py
  136. 136. Great, but...
  137. 137. Great, but...‣ Must start at same time
  138. 138. Great, but...‣ Must start at same time‣ Can’t replay missed logs
  139. 139. Great, but...‣ Must start at same time‣ Can’t replay missed logs‣ Race condition on cells
  140. 140. Great, but...‣ Must start at same time‣ Can’t replay missed logs‣ Race condition on cells‣ OLPC-specific transport!
  141. 141. YAPC::Tiny, 2009 跳格 Multiplayer SocialCalc 二零零九 唐鳳 字 中英雙宇有字版
  142. 142. EV/AnyEvent
  143. 143. Tatsumaki EV/AnyEvent @miyagawa
  144. 144. Tatsumaki EV/AnyEvent Web::Hippie @miyagawa @clkao
  145. 145. Tatsumaki EV/AnyEvent Web::Hippie Feersum @miyagawa @clkao @stash
  146. 146. WebSocket Channels multiserver.pl Web::Hippie Plack Feersum EV/libev
  147. 147. WebSocket Channels SpreadsheetControl multiserver.pl Web::HippieScheduleScheetCommand set A1 value n 2046 Plack RenderSheet Feersum EV/libev
  148. 148. WebSocket Channels SpreadsheetControl multiserver.pl Web::HippieScheduleScheetCommand set A1 value n 2046 Plack RenderSheet Send Feersum EV/libev
  149. 149. WebSocket Channels SpreadsheetControl multiserver.pl Web::Hippie RelayScheduleScheetCommand set A1 value n 2046 Plack RenderSheet Send Feersum EV/libev
  150. 150. WebSocket Channels SpreadsheetControl multiserver.pl Web::Hippie RelayScheduleScheetCommand set A1 value n 2046 Plack ScheduleScheetCommand RenderSheet Send Feersum set A1 value n 2046 (isRemote = true) EV/libev RenderSheet
  151. 151. New Features
  152. 152. New Features✓ Logs retrieved on join
  153. 153. New Features✓ Logs retrieved on join✓ Reconnection recovery
  154. 154. New Features✓ Logs retrieved on join✓ Reconnection recovery✓ Peer cursors are visible
  155. 155. New Features✓ Logs retrieved on join✓ Reconnection recovery✓ Peer cursors are visible✓ Cross-browser support!
  156. 156. New Features✓ Logs retrieved on join✓ Reconnection recovery✓ Peer cursors are visible✓ Cross-browser support!
  157. 157. Much better, but...
  158. 158. Much better, but...‣ Which peer’s log to take?
  159. 159. Much better, but...‣ Which peer’s log to take?‣ What if everyone leaves?
  160. 160. Much better, but...‣ Which peer’s log to take?‣ What if everyone leaves?‣ Who would keep the logs?
  161. 161. Much better, but...‣ Which peer’s log to take?‣ What if everyone leaves?‣ Who would keep the logs?‣ Replay 1,000+ commands?
  162. 162. Much better, but...‣ Which peer’s log to take?‣ What if everyone leaves?‣ Who would keep the logs?‣ Replay 1,000+ commands?
  163. 163. Undo
  164. 164. UndoRedo??
  165. 165. YAPC::NA, 2006
  166. 166. YAPC::NA, 2006“I think, but I cannot prove, that bythe next year JavaScript 2.0 willbootstrap itself, complete selfhosting, compile back to JavaScript,and replace Ruby as the Next BigThing in all environments. ”
  167. 167. YAPC::NA, 2006
  168. 168. YAPC::NA, 2006“JavaScript will become the commonbackend for all dynamic languages,and so you can write Perl to run in thebrowser, on the server, and insidedatabases, all with the same set ofdevelopment tools. ”
  169. 169. YAPC::NA, 2006
  170. 170. YAPC::NA, 2006“Because, as we all know,worse is better, so the worstscripting language is doomedto become the best.”
  171. 171. YAPC::NA, 2006“Because, as we all know,worse is better, so the worstscripting language is doomedto become the best.”
  172. 172. YAPC::NA, 2006“Because, as we all know,worse is better, so the worstscripting language is doomedto become the best.”
  173. 173. JS: Only The Good Parts JeremyAshkenas
  174. 174. JS: Only The Good Parts cs = (js) = js/2 JeremyAshkenas
  175. 175. JS: Only The Good Parts cs = (js) = js/2 JeremyAshkenas
  176. 176. JS: Only The Good Parts cs = (js) = js/2 “Original JavaScript: 22k LOC.  Ported to CoffeeScript: 5k LOC.  {async, jsdom, zappa, optimist etc}++” JeremyAshkenas
  177. 177. {x,y} = @offset
  178. 178. {x,y} = @offsetvar _ref = this.offset;
  179. 179. {x,y} = @offsetvar _ref = this.offset;var x = _ref.x;
  180. 180. {x,y} = @offsetvar _ref = this.offset;var x = _ref.x;var y = _ref.y;
  181. 181. {x,y} = @offsetvar _ref = this.offset;var x = _ref.x;var y = _ref.y; js2coffee.org
  182. 182. Function::ᵒ = (fun) -
  183. 183. Function::ᵒ = (fun) - (arg) = @ fun arg
  184. 184. Function::ᵒ = (fun) - (arg) = @ fun argf = (x) = x * 2
  185. 185. Function::ᵒ = (fun) - (arg) = @ fun argf = (x) = x * 2g = (x) = x * 3
  186. 186. Function::ᵒ = (fun) - (arg) = @ fun argf = (x) = x * 2g = (x) = x * 3h = f .ᵒ g
  187. 187. Function::ᵒ = (fun) - (arg) = @ fun argf = (x) = x * 2g = (x) = x * 3h = f .ᵒ gh 100 # 600
  188. 188. Function::ᵒ = (fun) - (arg) = @ fun argf = (x) = x * 2g = (x) = x * 3h = f .ᵒ gh 100 # 600
  189. 189. Zappa: Lazy Node.js zappajs.org
  190. 190. Zappa: Lazy Node.jsMauriceMachado zappajs.org
  191. 191. Zappa: Lazy Node.js “If you can describe it in 495 characters, why on earth shouldMaurice it take 879?”Machado zappajs.org
  192. 192. require(zappa) - @view layout: - html = body = @body @get /: - @render index @view index: - for name, value of { wiki: Wiki to HTML html: HTML to Wiki } form method: post, = p = textarea {name} p = input {type: submit, value}
  193. 193. require(zappa) - @view layout: - html = body = @body @get /: - @render index @view index: - for name, value of { wiki: Wiki to HTML html: HTML to Wiki } form method: post, = p = textarea {name} p = input {type: submit, value}
  194. 194. require(zappa) -@post /: - - @view layout: if @data.wiki? @body html = body = @send w2h @data.wiki @get /: - @render index else if @data.html? @send h2w @data.html @view index: - for name, value of { else redirect / wiki: Wiki to HTML html: HTML to Wiki } form method: post, = p = textarea {name} p = input {type: submit, value}
  195. 195. COSCUP, 2011
  196. 196. COSCUP, 2011
  197. 197. COSCUP, 2011hack
  198. 198.  hack
  199. 199.  hack
  200. 200.  ...
  201. 201. COSCUP, 2011hack
  202. 202.  hack
  203. 203.  hack
  204. 204.  ...
  205. 205. EtherCalc Edit Flow
  206. 206. EtherCalc Edit Flow main.coffee sc.coffee Socket.ioSocialCalc.js Express Node.js db.coffee EV/libuv redis.js Zappa
  207. 207. EtherCalc Edit Flow main.coffee sc.coffee Socket.ioSocialCalc.js Express Node.js db.coffee EV/libuv redis.js Zappa Redis(optional)
  208. 208. EtherCalc Edit Flow main.coffee sc.coffee Socket.ioSocialCalc.js Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js Redis(optional)
  209. 209. EtherCalc Edit Flow main.coffee MULTI sc.coffee GET snapshot Socket.io LRANGE logSocialCalc.js EXEC Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js Redis(optional)
  210. 210. EtherCalc Edit Flow main.coffee MULTI sc.coffee GET snapshot Socket.io LRANGE logSocialCalc.js EXEC Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js RPUSH log cmd Redis(optional)
  211. 211. EtherCalc Edit Flow main.coffee MULTI sc.coffee GET snapshot Socket.io LRANGE logSocialCalc.js EXEC Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js RPUSH log cmd Redis(optional)
  212. 212. EtherCalc Edit Flow main.coffee MULTI sc.coffee GET snapshot Socket.io LRANGE logSocialCalc.js EXEC Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js RPUSH log cmd Redis(optional)
  213. 213. EtherCalc Edit Flow main.coffee MULTI sc.coffee GET snapshot Socket.io LRANGE logSocialCalc.js EXEC Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js MULTI RPUSH log cmd Redis DEL log(optional) SET snapshot snapshot EXEC
  214. 214. Recalc Subscription
  215. 215. Recalc Subscription
  216. 216. Recalc Subscription
  217. 217. Recalc Subscription ask.log: Foo
  218. 218. Recalc Subscription ask.log: Foo log: Foo,snapshot,log
  219. 219. Recalc Subscription ask.log: Foo log: Foo,snapshot,log execute: set A1 formula Bar!B2
  220. 220. Recalc Subscription ask.log: Foo log: Foo,snapshot,log execute: set A1 formula Bar!B2 ask.recalc: Bar
  221. 221. Recalc Subscription ask.log: Foo log: Foo,snapshot,log execute: set A1 formula Bar!B2 ask.recalc: Bar recalc: Bar,snapshot
  222. 222. Recalc Subscription ask.log: Foo log: Foo,snapshot,log execute: set A1 formula Bar!B2 ask.recalc: Bar recalc: Bar,snapshot recalc: Bar,snapshot
  223. 223. PaaS Deployment
  224. 224. PaaS Deployment stackato.yml app.js
  225. 225. PaaS Deployment stackato.yml app.js dotcloud.yml server.js
  226. 226. PaaS Deployment stackato.yml app.js dotcloud.yml server.js server.js
  227. 227. REST Interface
  228. 228. REST InterfaceGET /_/pagePUT /_/page
  229. 229. REST InterfaceGET /_/page POST /_/pagePUT /_/page {command:[…]}
  230. 230. REST InterfaceGET /_/page POST /_/pagePUT /_/page {command:[…]} GET /_/page/cells/A1 PUT /_/page/cells/A1 GET /_/page/names/range
  231. 231. TODO, 2012
  232. 232. TODO, 2012‣ Export/Import
  233. 233. TODO, 2012‣ Export/Import‣ Chat Presence
  234. 234. TODO, 2012‣ Export/Import‣ Chat Presence‣ Socialtext Integration
  235. 235. TODO, 2012‣ Export/Import‣ Chat Presence‣ Socialtext Integration‣ Drupal Integration
  236. 236. TODO, 2012‣ Export/Import‣ Chat Presence‣ Socialtext Integration‣ Drupal Integration‣ Forks welcome!
  237. 237. Thank you! EtherCalc Multiplayer Spreadsheet
  238. 238. EtherCalcThe person who associated a workwith this document has dedicatedthe work to the Commons bywaiving all of his or her rights to thework worldwide under copyright lawand all related or neighboring legalrights he or she had in the work, tothe extent allowable by law.Works under CC0 do not requireattribution. ethercalc.net

×