vkhater-social_stream-base 0.11.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (629) hide show
  1. data/.gitignore +16 -0
  2. data/.rspec +1 -0
  3. data/.yardopts +2 -0
  4. data/Gemfile +10 -0
  5. data/LICENSE +20 -0
  6. data/README.rdoc +68 -0
  7. data/Rakefile +35 -0
  8. data/app/assets/images/HTML5.png +0 -0
  9. data/app/assets/images/HTML5_Semantics.png +0 -0
  10. data/app/assets/images/HTML5_Styling.png +0 -0
  11. data/app/assets/images/Jcrop.gif +0 -0
  12. data/app/assets/images/arrow-end.png +0 -0
  13. data/app/assets/images/arrow-start.png +0 -0
  14. data/app/assets/images/arrow.png +0 -0
  15. data/app/assets/images/big-logo.png +0 -0
  16. data/app/assets/images/btn/1-facebook.png +0 -0
  17. data/app/assets/images/btn/_notes/btn_certificates.png.mno +4 -0
  18. data/app/assets/images/btn/activity.png +0 -0
  19. data/app/assets/images/btn/arrowBlue.png +0 -0
  20. data/app/assets/images/btn/arrow_session_change.png +0 -0
  21. data/app/assets/images/btn/arrows-ffffff.png +0 -0
  22. data/app/assets/images/btn/bold.png +0 -0
  23. data/app/assets/images/btn/btn_account.png +0 -0
  24. data/app/assets/images/btn/btn_activities.png +0 -0
  25. data/app/assets/images/btn/btn_bookmark.png +0 -0
  26. data/app/assets/images/btn/btn_browse.png +0 -0
  27. data/app/assets/images/btn/btn_check.png +0 -0
  28. data/app/assets/images/btn/btn_close.png +0 -0
  29. data/app/assets/images/btn/btn_comment.png +0 -0
  30. data/app/assets/images/btn/btn_comment_add.png +0 -0
  31. data/app/assets/images/btn/btn_config.png +0 -0
  32. data/app/assets/images/btn/btn_date.png +0 -0
  33. data/app/assets/images/btn/btn_delete.png +0 -0
  34. data/app/assets/images/btn/btn_down.png +0 -0
  35. data/app/assets/images/btn/btn_edit.png +0 -0
  36. data/app/assets/images/btn/btn_exit.png +0 -0
  37. data/app/assets/images/btn/btn_find.png +0 -0
  38. data/app/assets/images/btn/btn_follow.png +0 -0
  39. data/app/assets/images/btn/btn_foward.png +0 -0
  40. data/app/assets/images/btn/btn_friend.png +0 -0
  41. data/app/assets/images/btn/btn_gallery.png +0 -0
  42. data/app/assets/images/btn/btn_group.png +0 -0
  43. data/app/assets/images/btn/btn_help.png +0 -0
  44. data/app/assets/images/btn/btn_home.png +0 -0
  45. data/app/assets/images/btn/btn_inbox.png +0 -0
  46. data/app/assets/images/btn/btn_info.png +0 -0
  47. data/app/assets/images/btn/btn_invitation.png +0 -0
  48. data/app/assets/images/btn/btn_like.png +0 -0
  49. data/app/assets/images/btn/btn_next.png +0 -0
  50. data/app/assets/images/btn/btn_notification.png +0 -0
  51. data/app/assets/images/btn/btn_notification_delete.png +0 -0
  52. data/app/assets/images/btn/btn_notification_read.png +0 -0
  53. data/app/assets/images/btn/btn_notifications.png +0 -0
  54. data/app/assets/images/btn/btn_page_link.png +0 -0
  55. data/app/assets/images/btn/btn_partner.png +0 -0
  56. data/app/assets/images/btn/btn_photo.png +0 -0
  57. data/app/assets/images/btn/btn_play.png +0 -0
  58. data/app/assets/images/btn/btn_printer.png +0 -0
  59. data/app/assets/images/btn/btn_profile.png +0 -0
  60. data/app/assets/images/btn/btn_rank.png +0 -0
  61. data/app/assets/images/btn/btn_read.png +0 -0
  62. data/app/assets/images/btn/btn_security.png +0 -0
  63. data/app/assets/images/btn/btn_send.png +0 -0
  64. data/app/assets/images/btn/btn_spam.png +0 -0
  65. data/app/assets/images/btn/btn_star.png +0 -0
  66. data/app/assets/images/btn/btn_tag.png +0 -0
  67. data/app/assets/images/btn/btn_write.png +0 -0
  68. data/app/assets/images/btn/close.png +0 -0
  69. data/app/assets/images/btn/date.png +0 -0
  70. data/app/assets/images/btn/delete.png +0 -0
  71. data/app/assets/images/btn/download.png +0 -0
  72. data/app/assets/images/btn/edit.png +0 -0
  73. data/app/assets/images/btn/error.png +0 -0
  74. data/app/assets/images/btn/facebook.png +0 -0
  75. data/app/assets/images/btn/flag.png +0 -0
  76. data/app/assets/images/btn/group_left.png +0 -0
  77. data/app/assets/images/btn/group_right.png +0 -0
  78. data/app/assets/images/btn/header_notifications.png +0 -0
  79. data/app/assets/images/btn/index_71.png +0 -0
  80. data/app/assets/images/btn/info.png +0 -0
  81. data/app/assets/images/btn/italic.png +0 -0
  82. data/app/assets/images/btn/like.png +0 -0
  83. data/app/assets/images/btn/linkedin.png +0 -0
  84. data/app/assets/images/btn/message_conversation.png +0 -0
  85. data/app/assets/images/btn/message_inbox.png +0 -0
  86. data/app/assets/images/btn/message_new.png +0 -0
  87. data/app/assets/images/btn/message_sentbox.png +0 -0
  88. data/app/assets/images/btn/message_trash.png +0 -0
  89. data/app/assets/images/btn/new.png +0 -0
  90. data/app/assets/images/btn/next_conference.png +0 -0
  91. data/app/assets/images/btn/next_space.png +0 -0
  92. data/app/assets/images/btn/nolike.png +0 -0
  93. data/app/assets/images/btn/notifications.png +0 -0
  94. data/app/assets/images/btn/pixel.png +0 -0
  95. data/app/assets/images/btn/point_blue.png +0 -0
  96. data/app/assets/images/btn/point_gray.png +0 -0
  97. data/app/assets/images/btn/post.png +0 -0
  98. data/app/assets/images/btn/search.png +0 -0
  99. data/app/assets/images/btn/search_icon.png +0 -0
  100. data/app/assets/images/btn/shadow.png +0 -0
  101. data/app/assets/images/btn/share.png +0 -0
  102. data/app/assets/images/btn/subtime.png +0 -0
  103. data/app/assets/images/btn/success.png +0 -0
  104. data/app/assets/images/btn/tag_cloud.png +0 -0
  105. data/app/assets/images/btn/twitter-follow-icon.png +0 -0
  106. data/app/assets/images/btn/twitter.png +0 -0
  107. data/app/assets/images/btn/uno.png +0 -0
  108. data/app/assets/images/btn/viewer.png +0 -0
  109. data/app/assets/images/btn/warning.png +0 -0
  110. data/app/assets/images/cancel.png +0 -0
  111. data/app/assets/images/cleditor/buttons.gif +0 -0
  112. data/app/assets/images/cleditor/toolbar.gif +0 -0
  113. data/app/assets/images/frontpage/collaborate.png +0 -0
  114. data/app/assets/images/frontpage/comments.png +0 -0
  115. data/app/assets/images/frontpage/green_sq.png +0 -0
  116. data/app/assets/images/frontpage/meet.png +0 -0
  117. data/app/assets/images/frontpage/people.png +0 -0
  118. data/app/assets/images/frontpage/purple_sq.png +0 -0
  119. data/app/assets/images/frontpage/right_comments.gif +0 -0
  120. data/app/assets/images/frontpage/right_conference.png +0 -0
  121. data/app/assets/images/frontpage/right_organizers.gif +0 -0
  122. data/app/assets/images/frontpage/right_people.gif +0 -0
  123. data/app/assets/images/frontpage/right_social.gif +0 -0
  124. data/app/assets/images/frontpage/right_tags.gif +0 -0
  125. data/app/assets/images/frontpage/right_webcam.gif +0 -0
  126. data/app/assets/images/frontpage/share.png +0 -0
  127. data/app/assets/images/frontpage/tags.png +0 -0
  128. data/app/assets/images/frontpage/yellow_sq.png +0 -0
  129. data/app/assets/images/header-logo.png +0 -0
  130. data/app/assets/images/html5-badge-h-css3-semantics.png +0 -0
  131. data/app/assets/images/icon_checkbox.png +0 -0
  132. data/app/assets/images/icons/favicon.ico +0 -0
  133. data/app/assets/images/left.png +0 -0
  134. data/app/assets/images/lightbox-blank.gif +0 -0
  135. data/app/assets/images/lightbox-btn-close.gif +0 -0
  136. data/app/assets/images/lightbox-btn-next.gif +0 -0
  137. data/app/assets/images/lightbox-btn-prev.gif +0 -0
  138. data/app/assets/images/lightbox-ico-loading.gif +0 -0
  139. data/app/assets/images/loader.gif +0 -0
  140. data/app/assets/images/loading.gif +0 -0
  141. data/app/assets/images/logo.png +0 -0
  142. data/app/assets/images/logos/actor/group.png +0 -0
  143. data/app/assets/images/logos/actor/remote_subject.png +0 -0
  144. data/app/assets/images/logos/actor/remote_user.png +0 -0
  145. data/app/assets/images/logos/actor/user.png +0 -0
  146. data/app/assets/images/logos/contact/group.png +0 -0
  147. data/app/assets/images/logos/contact/user.png +0 -0
  148. data/app/assets/images/logos/original/group.png +0 -0
  149. data/app/assets/images/logos/original/user.png +0 -0
  150. data/app/assets/images/logos/profile/group.png +0 -0
  151. data/app/assets/images/logos/profile/user.png +0 -0
  152. data/app/assets/images/logos/representation/group.png +0 -0
  153. data/app/assets/images/logos/representation/user.png +0 -0
  154. data/app/assets/images/mini-loading.gif +0 -0
  155. data/app/assets/images/right.png +0 -0
  156. data/app/assets/images/tipsy.gif +0 -0
  157. data/app/assets/javascripts/activities.js.erb +250 -0
  158. data/app/assets/javascripts/activities_security_chosen-modified.jquery.js +767 -0
  159. data/app/assets/javascripts/cheesecake.js +6 -0
  160. data/app/assets/javascripts/contacts.js +4 -0
  161. data/app/assets/javascripts/conversations.js +3 -0
  162. data/app/assets/javascripts/groups.js +5 -0
  163. data/app/assets/javascripts/invitations.js +8 -0
  164. data/app/assets/javascripts/jquery.ad-gallery.js +850 -0
  165. data/app/assets/javascripts/jquery.ad-gallery.pack.js +10 -0
  166. data/app/assets/javascripts/layouts.js +21 -0
  167. data/app/assets/javascripts/messages.js +4 -0
  168. data/app/assets/javascripts/posts.js +1 -0
  169. data/app/assets/javascripts/preloader.js +6 -0
  170. data/app/assets/javascripts/profiles.js +9 -0
  171. data/app/assets/javascripts/relation_customs.js +32 -0
  172. data/app/assets/javascripts/search.js.erb +3 -0
  173. data/app/assets/javascripts/settings.js +14 -0
  174. data/app/assets/javascripts/social_stream-base.js +11 -0
  175. data/app/assets/javascripts/ties.js +67 -0
  176. data/app/assets/javascripts/toolbar.js +1 -0
  177. data/app/assets/javascripts/users.js +2 -0
  178. data/app/assets/stylesheets/0_devise_sign.css +28 -0
  179. data/app/assets/stylesheets/_colors.scss +25 -0
  180. data/app/assets/stylesheets/activities.css.scss +88 -0
  181. data/app/assets/stylesheets/base.css.scss +257 -0
  182. data/app/assets/stylesheets/cheesecake.css.scss +55 -0
  183. data/app/assets/stylesheets/contacts.css.scss +100 -0
  184. data/app/assets/stylesheets/conversations.css +4 -0
  185. data/app/assets/stylesheets/footer.css.scss +22 -0
  186. data/app/assets/stylesheets/frontpage.css.scss +70 -0
  187. data/app/assets/stylesheets/groups.css +4 -0
  188. data/app/assets/stylesheets/header.css.scss +203 -0
  189. data/app/assets/stylesheets/home.css.scss +53 -0
  190. data/app/assets/stylesheets/images/add-policy.png +0 -0
  191. data/app/assets/stylesheets/images/fcbkcomplete/close.gif +0 -0
  192. data/app/assets/stylesheets/images/loading.gif +0 -0
  193. data/app/assets/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  194. data/app/assets/stylesheets/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  195. data/app/assets/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  196. data/app/assets/stylesheets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  197. data/app/assets/stylesheets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  198. data/app/assets/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  199. data/app/assets/stylesheets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  200. data/app/assets/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  201. data/app/assets/stylesheets/images/ui-icons_222222_256x240.png +0 -0
  202. data/app/assets/stylesheets/images/ui-icons_2e83ff_256x240.png +0 -0
  203. data/app/assets/stylesheets/images/ui-icons_454545_256x240.png +0 -0
  204. data/app/assets/stylesheets/images/ui-icons_888888_256x240.png +0 -0
  205. data/app/assets/stylesheets/images/ui-icons_cd0a0a_256x240.png +0 -0
  206. data/app/assets/stylesheets/invitations.css +3 -0
  207. data/app/assets/stylesheets/location.css.scss +38 -0
  208. data/app/assets/stylesheets/menu.css.scss +19 -0
  209. data/app/assets/stylesheets/messages.css.scss +141 -0
  210. data/app/assets/stylesheets/opa75.png +0 -0
  211. data/app/assets/stylesheets/profiles.css +4 -0
  212. data/app/assets/stylesheets/relation_customs.css.scss +233 -0
  213. data/app/assets/stylesheets/search.css.scss +165 -0
  214. data/app/assets/stylesheets/settings.css +9 -0
  215. data/app/assets/stylesheets/social_stream-base.css +5 -0
  216. data/app/assets/stylesheets/ties.css.scss +12 -0
  217. data/app/assets/stylesheets/toolbar.css +10 -0
  218. data/app/assets/stylesheets/users.css +4 -0
  219. data/app/controllers/activities_controller.rb +19 -0
  220. data/app/controllers/api_controller.rb +38 -0
  221. data/app/controllers/authentications_controller.rb +17 -0
  222. data/app/controllers/cheesecake_controller.rb +9 -0
  223. data/app/controllers/comments_controller.rb +8 -0
  224. data/app/controllers/contacts_controller.rb +95 -0
  225. data/app/controllers/conversations_controller.rb +102 -0
  226. data/app/controllers/frontpage_controller.rb +23 -0
  227. data/app/controllers/groups_controller.rb +58 -0
  228. data/app/controllers/home_controller.rb +3 -0
  229. data/app/controllers/invitations_controller.rb +36 -0
  230. data/app/controllers/likes_controller.rb +41 -0
  231. data/app/controllers/messages_controller.rb +87 -0
  232. data/app/controllers/notifications_controller.rb +73 -0
  233. data/app/controllers/omniauth_callbacks_controller.rb +17 -0
  234. data/app/controllers/permissions_controller.rb +15 -0
  235. data/app/controllers/posts_controller.rb +3 -0
  236. data/app/controllers/profiles_controller.rb +9 -0
  237. data/app/controllers/relation/customs_controller.rb +6 -0
  238. data/app/controllers/search_controller.rb +79 -0
  239. data/app/controllers/settings_controller.rb +43 -0
  240. data/app/controllers/subjects_controller.rb +7 -0
  241. data/app/controllers/tags_controller.rb +15 -0
  242. data/app/controllers/ties_controller.rb +11 -0
  243. data/app/controllers/users_controller.rb +31 -0
  244. data/app/helpers/activities_helper.rb +37 -0
  245. data/app/helpers/contacts_helper.rb +24 -0
  246. data/app/helpers/groups_helper.rb +3 -0
  247. data/app/helpers/location_helper.rb +46 -0
  248. data/app/helpers/permissions_helper.rb +16 -0
  249. data/app/helpers/profiles_helper.rb +37 -0
  250. data/app/helpers/search_helper.rb +38 -0
  251. data/app/helpers/settings_helper.rb +9 -0
  252. data/app/helpers/sidebar_helper.rb +10 -0
  253. data/app/helpers/subjects_helper.rb +15 -0
  254. data/app/helpers/toolbar_helper.rb +109 -0
  255. data/app/helpers/users_helper.rb +4 -0
  256. data/app/mailers/invitation_mailer.rb +11 -0
  257. data/app/models/ability.rb +2 -0
  258. data/app/models/activity.rb +390 -0
  259. data/app/models/activity_object.rb +64 -0
  260. data/app/models/activity_object_activity.rb +14 -0
  261. data/app/models/activity_verb.rb +22 -0
  262. data/app/models/actor.rb +553 -0
  263. data/app/models/audience.rb +9 -0
  264. data/app/models/authentication.rb +3 -0
  265. data/app/models/comment.rb +10 -0
  266. data/app/models/contact.rb +209 -0
  267. data/app/models/group.rb +51 -0
  268. data/app/models/like.rb +49 -0
  269. data/app/models/permission.rb +52 -0
  270. data/app/models/post.rb +12 -0
  271. data/app/models/profile.rb +58 -0
  272. data/app/models/relation.rb +169 -0
  273. data/app/models/relation/custom.rb +112 -0
  274. data/app/models/relation/public.rb +11 -0
  275. data/app/models/relation/reject.rb +3 -0
  276. data/app/models/relation/single.rb +22 -0
  277. data/app/models/relation_permission.rb +4 -0
  278. data/app/models/tie.rb +147 -0
  279. data/app/models/user.rb +148 -0
  280. data/app/views/activities/_activity.html.erb +5 -0
  281. data/app/views/activities/_child.html.erb +18 -0
  282. data/app/views/activities/_comments.html.erb +3 -0
  283. data/app/views/activities/_filter.html.erb +83 -0
  284. data/app/views/activities/_index.html.erb +14 -0
  285. data/app/views/activities/_new.html.erb +56 -0
  286. data/app/views/activities/_options.html.erb +27 -0
  287. data/app/views/activities/_root.html.erb +37 -0
  288. data/app/views/activities/_wall.html.erb +5 -0
  289. data/app/views/activities/index.html.erb +0 -0
  290. data/app/views/activities/index.js.erb +3 -0
  291. data/app/views/activity_objects/_activity_object.html.erb +7 -0
  292. data/app/views/actors/_actor.html.erb +0 -0
  293. data/app/views/actors/_actor_cheesecake.html.erb +4 -0
  294. data/app/views/api/activity_atom_feed.atom.builder +40 -0
  295. data/app/views/avatars/index.html.erb +15 -0
  296. data/app/views/avatars/update.js.erb +15 -0
  297. data/app/views/cheesecake/_index.html.erb +38 -0
  298. data/app/views/cheesecake/index.html.erb +10 -0
  299. data/app/views/comments/_comment.html.erb +1 -0
  300. data/app/views/comments/_new.html.erb +47 -0
  301. data/app/views/comments/create.js.erb +10 -0
  302. data/app/views/comments/destroy.js.erb +1 -0
  303. data/app/views/contacts/_contact.html.erb +20 -0
  304. data/app/views/contacts/_form.html.erb +38 -0
  305. data/app/views/contacts/_index.html.erb +40 -0
  306. data/app/views/contacts/_link.html.erb +9 -0
  307. data/app/views/contacts/_pendings.html.erb +18 -0
  308. data/app/views/contacts/_suggestions.html.erb +15 -0
  309. data/app/views/contacts/_suggestions_and_pendings.html.erb +6 -0
  310. data/app/views/contacts/destroy.js.erb +6 -0
  311. data/app/views/contacts/edit.html.erb +6 -0
  312. data/app/views/contacts/index.html.erb +37 -0
  313. data/app/views/contacts/index.js.erb +3 -0
  314. data/app/views/contacts/new.html.erb +5 -0
  315. data/app/views/contacts/suggestion.html.erb +1 -0
  316. data/app/views/contacts/suggestion.js.erb +1 -0
  317. data/app/views/conversations/_conversation.html.erb +38 -0
  318. data/app/views/conversations/_conversation_full.html.erb +71 -0
  319. data/app/views/conversations/_conversations.html.erb +5 -0
  320. data/app/views/conversations/_index.html.erb +11 -0
  321. data/app/views/conversations/_show.html.erb +13 -0
  322. data/app/views/conversations/edit.html.erb +10 -0
  323. data/app/views/conversations/index.html.erb +15 -0
  324. data/app/views/conversations/index.js.erb +6 -0
  325. data/app/views/conversations/show.html.erb +33 -0
  326. data/app/views/conversations/show.js.erb +26 -0
  327. data/app/views/devise/passwords/edit.html.erb +21 -0
  328. data/app/views/devise/passwords/new.html.erb +27 -0
  329. data/app/views/devise/registrations/_delete_account.html.erb +20 -0
  330. data/app/views/devise/registrations/_edit_user.html.erb +113 -0
  331. data/app/views/devise/registrations/edit.html.erb +20 -0
  332. data/app/views/devise/registrations/new.html.erb +44 -0
  333. data/app/views/devise/sessions/new.html.erb +35 -0
  334. data/app/views/devise/shared/_links.erb +25 -0
  335. data/app/views/frontpage/_caracteristics.html.erb +23 -0
  336. data/app/views/frontpage/_social_networks.html.erb +3 -0
  337. data/app/views/frontpage/_sponsor.html.erb +12 -0
  338. data/app/views/frontpage/host_meta.xml.builder +11 -0
  339. data/app/views/frontpage/index.html.erb +69 -0
  340. data/app/views/groups/_group.html.erb +4 -0
  341. data/app/views/groups/_group_focus_search.html.erb +2 -0
  342. data/app/views/groups/_group_global_search.html.erb +2 -0
  343. data/app/views/groups/_group_with_details.html.erb +2 -0
  344. data/app/views/groups/_index.html.erb +19 -0
  345. data/app/views/groups/_new.html.erb +81 -0
  346. data/app/views/groups/_show.html.erb +33 -0
  347. data/app/views/groups/_tag_cloud.html.erb +25 -0
  348. data/app/views/groups/index.html.erb +57 -0
  349. data/app/views/groups/index.js.erb +1 -0
  350. data/app/views/groups/new.html.erb +9 -0
  351. data/app/views/groups/show.html.erb +1 -0
  352. data/app/views/groups/show.js.erb +2 -0
  353. data/app/views/home/_groups.html.erb +24 -0
  354. data/app/views/home/index.html.erb +19 -0
  355. data/app/views/home/index.js.erb +5 -0
  356. data/app/views/invitation_mailer/send_invitation.html.erb +79 -0
  357. data/app/views/invitation_mailer/send_invitation.text.erb +21 -0
  358. data/app/views/invitations/_new.html.erb +28 -0
  359. data/app/views/invitations/new.html.erb +9 -0
  360. data/app/views/invitations/new.js.erb +4 -0
  361. data/app/views/layouts/_account.html.erb +18 -0
  362. data/app/views/layouts/_flash.html.erb +5 -0
  363. data/app/views/layouts/_footer.html.erb +16 -0
  364. data/app/views/layouts/_header.erb +5 -0
  365. data/app/views/layouts/_header_dropdown_menu.html.erb +19 -0
  366. data/app/views/layouts/_header_dropdown_menu_sessions.html.erb +14 -0
  367. data/app/views/layouts/_header_signed_in.erb +45 -0
  368. data/app/views/layouts/_header_signed_out.erb +34 -0
  369. data/app/views/layouts/_representation.html.erb +28 -0
  370. data/app/views/layouts/_search.html.erb +62 -0
  371. data/app/views/layouts/_settings.html.erb +18 -0
  372. data/app/views/layouts/application.html.erb +60 -0
  373. data/app/views/layouts/frontpage.html.erb +43 -0
  374. data/app/views/likes/create.js.erb +2 -0
  375. data/app/views/likes/destroy.js.erb +1 -0
  376. data/app/views/location/_location.html.erb +3 -0
  377. data/app/views/location/_location_body.html.erb +18 -0
  378. data/app/views/message_mailer/new_message_email.html.erb +35 -0
  379. data/app/views/message_mailer/new_message_email.text.erb +8 -0
  380. data/app/views/message_mailer/reply_message_email.html.erb +35 -0
  381. data/app/views/message_mailer/reply_message_email.text.erb +8 -0
  382. data/app/views/messages/_form.html.erb +39 -0
  383. data/app/views/messages/_message.html.erb +31 -0
  384. data/app/views/messages/_new.html.erb +10 -0
  385. data/app/views/messages/new.html.erb +37 -0
  386. data/app/views/messages/new.js.erb +28 -0
  387. data/app/views/notification_mailer/new_notification_email.html.erb +35 -0
  388. data/app/views/notification_mailer/new_notification_email.text.erb +9 -0
  389. data/app/views/notifications/_index.html.erb +21 -0
  390. data/app/views/notifications/_notification.html.erb +41 -0
  391. data/app/views/notifications/activities/_follow.html.erb +10 -0
  392. data/app/views/notifications/activities/_follow.text.erb +8 -0
  393. data/app/views/notifications/activities/_like.html.erb +30 -0
  394. data/app/views/notifications/activities/_like.text.erb +23 -0
  395. data/app/views/notifications/activities/_make-friend.html.erb +10 -0
  396. data/app/views/notifications/activities/_make-friend.text.erb +7 -0
  397. data/app/views/notifications/activities/_post.html.erb +22 -0
  398. data/app/views/notifications/activities/_post.text.erb +17 -0
  399. data/app/views/notifications/activities/_update.html.erb +18 -0
  400. data/app/views/notifications/activities/_update.text.erb +15 -0
  401. data/app/views/notifications/index.html.erb +13 -0
  402. data/app/views/notifications/index.js.erb +6 -0
  403. data/app/views/objects/_destroy.js.erb +2 -0
  404. data/app/views/objects/_new_activity.html.erb +8 -0
  405. data/app/views/objects/_show.html.erb +3 -0
  406. data/app/views/permissions/_index.html.erb +35 -0
  407. data/app/views/permissions/index.js.erb +15 -0
  408. data/app/views/posts/_new_activity.html.erb +1 -0
  409. data/app/views/posts/_new_activity_fields.erb +7 -0
  410. data/app/views/posts/_post.html.erb +3 -0
  411. data/app/views/posts/_post_focus_search.html.erb +37 -0
  412. data/app/views/posts/_post_global_search.html.erb +18 -0
  413. data/app/views/posts/_post_with_details.html.erb +3 -0
  414. data/app/views/posts/create.js.erb +7 -0
  415. data/app/views/posts/destroy.js.erb +1 -0
  416. data/app/views/posts/show.html.erb +10 -0
  417. data/app/views/profiles/_contact.html.erb +81 -0
  418. data/app/views/profiles/_experience.html.erb +22 -0
  419. data/app/views/profiles/_personal.html.erb +74 -0
  420. data/app/views/profiles/_profile.html.erb +40 -0
  421. data/app/views/profiles/_tags.html.erb +22 -0
  422. data/app/views/profiles/edit.html.erb +205 -0
  423. data/app/views/profiles/show.html.erb +22 -0
  424. data/app/views/profiles/update.js.erb +20 -0
  425. data/app/views/relation/customs/_form.html.erb +29 -0
  426. data/app/views/relation/customs/_list.html.erb +63 -0
  427. data/app/views/relation/customs/_update_rules.js.erb +5 -0
  428. data/app/views/relation/customs/create.js.erb +21 -0
  429. data/app/views/relation/customs/index.html.erb +43 -0
  430. data/app/views/relation/customs/update.js.erb +11 -0
  431. data/app/views/search/_extended_search.html.erb +19 -0
  432. data/app/views/search/_form.html.erb +54 -0
  433. data/app/views/search/_header_search.html.erb +16 -0
  434. data/app/views/search/_index.html.erb +12 -0
  435. data/app/views/search/index.html.erb +9 -0
  436. data/app/views/search/index.js.erb +22 -0
  437. data/app/views/settings/_api_key.html.erb +26 -0
  438. data/app/views/settings/_destroy.html.erb +17 -0
  439. data/app/views/settings/_index.html.erb +8 -0
  440. data/app/views/settings/_notifications.html.erb +34 -0
  441. data/app/views/settings/index.html.erb +16 -0
  442. data/app/views/settings/index.js.erb +7 -0
  443. data/app/views/subjects/_contacts.html.erb +18 -0
  444. data/app/views/subjects/_show.js.erb +5 -0
  445. data/app/views/subjects/_subject.html.erb +8 -0
  446. data/app/views/subjects/_subject_with_details.html.erb +17 -0
  447. data/app/views/ties/index.html.erb +8 -0
  448. data/app/views/toolbar/_home.html.erb +15 -0
  449. data/app/views/toolbar/_logo.html.erb +23 -0
  450. data/app/views/toolbar/_messages.html.erb +11 -0
  451. data/app/views/toolbar/_profile.html.erb +24 -0
  452. data/app/views/toolbar/_subject.html.erb +10 -0
  453. data/app/views/users/_groups.html.erb +22 -0
  454. data/app/views/users/_index.html.erb +19 -0
  455. data/app/views/users/_show.html.erb +34 -0
  456. data/app/views/users/_user.html.erb +2 -0
  457. data/app/views/users/_user_focus_search.html.erb +2 -0
  458. data/app/views/users/_user_global_search.html.erb +2 -0
  459. data/app/views/users/_user_with_details.html.erb +2 -0
  460. data/app/views/users/index.html.erb +41 -0
  461. data/app/views/users/index.js.erb +1 -0
  462. data/app/views/users/info.html.erb +0 -0
  463. data/app/views/users/show.html.erb +1 -0
  464. data/app/views/users/show.js.erb +2 -0
  465. data/app/views/users/show.xml.builder +15 -0
  466. data/config/locales/en.yml +472 -0
  467. data/config/locales/es.yml +470 -0
  468. data/config/routes.rb +102 -0
  469. data/db/migrate/20110610112023_create_social_stream.rb +319 -0
  470. data/db/migrate/20110705103202_empty_ties_count.rb +17 -0
  471. data/db/migrate/20110712090343_remove_spheres.rb +30 -0
  472. data/db/migrate/20110712142140_remove_permission_function.rb +26 -0
  473. data/db/migrate/20110912074426_add_reject_relation.rb +29 -0
  474. data/db/migrate/20111124100618_object_actors.rb +52 -0
  475. data/db/migrate/20111221103509_add_language_field.rb +13 -0
  476. data/lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb +37 -0
  477. data/lib/acts_as_taggable_on/social_stream.rb +58 -0
  478. data/lib/generators/social_stream/base/install_generator.rb +66 -0
  479. data/lib/generators/social_stream/base/templates/initializer.rb +32 -0
  480. data/lib/generators/social_stream/base/templates/navigation.rb +4 -0
  481. data/lib/generators/social_stream/base/templates/relations.yml +39 -0
  482. data/lib/generators/social_stream/base/templates/sphinx.yml +9 -0
  483. data/lib/paperclip/social_stream.rb +6 -0
  484. data/lib/social_stream-base.rb +104 -0
  485. data/lib/social_stream/ability.rb +7 -0
  486. data/lib/social_stream/ability/base.rb +101 -0
  487. data/lib/social_stream/base/dependencies.rb +47 -0
  488. data/lib/social_stream/base/engine.rb +69 -0
  489. data/lib/social_stream/base/version.rb +5 -0
  490. data/lib/social_stream/controllers/cancan_devise_integration.rb +33 -0
  491. data/lib/social_stream/controllers/helpers.rb +135 -0
  492. data/lib/social_stream/controllers/objects.rb +39 -0
  493. data/lib/social_stream/d3.rb +53 -0
  494. data/lib/social_stream/migrations/base.rb +58 -0
  495. data/lib/social_stream/migrations/components.rb +19 -0
  496. data/lib/social_stream/models/object.rb +133 -0
  497. data/lib/social_stream/models/subject.rb +118 -0
  498. data/lib/social_stream/models/supertype.rb +37 -0
  499. data/lib/social_stream/populate.rb +26 -0
  500. data/lib/social_stream/test_helpers.rb +11 -0
  501. data/lib/social_stream/test_helpers/controllers.rb +122 -0
  502. data/lib/social_stream/toolbar_config/base.rb +94 -0
  503. data/lib/social_stream/views/list.rb +17 -0
  504. data/lib/social_stream/views/settings/base.rb +43 -0
  505. data/lib/social_stream/views/sidebar/base.rb +27 -0
  506. data/lib/tasks/db/populate.rake +241 -0
  507. data/lib/tasks/workers.rake +163 -0
  508. data/social_stream-base.gemspec +83 -0
  509. data/spec/controllers/comments_controller_spec.rb +66 -0
  510. data/spec/controllers/contacts_controller_spec.rb +111 -0
  511. data/spec/controllers/frontpage_controller_spec.rb +16 -0
  512. data/spec/controllers/groups_controller_spec.rb +178 -0
  513. data/spec/controllers/home_controller_spec.rb +56 -0
  514. data/spec/controllers/invitations_controller_spec.rb +34 -0
  515. data/spec/controllers/likes_controller_spec.rb +48 -0
  516. data/spec/controllers/notifications_controller_spec.rb +46 -0
  517. data/spec/controllers/permissions_controller_spec.rb +45 -0
  518. data/spec/controllers/posts_controller_spec.rb +233 -0
  519. data/spec/controllers/profiles_controller_spec.rb +102 -0
  520. data/spec/controllers/relation_customs_controller_spec.rb +139 -0
  521. data/spec/controllers/representations_spec.rb +74 -0
  522. data/spec/controllers/settings_controller_spec.rb +41 -0
  523. data/spec/controllers/subjects_controller.rb +14 -0
  524. data/spec/controllers/users_controller_spec.rb +98 -0
  525. data/spec/dummy/.gitignore +5 -0
  526. data/spec/dummy/Rakefile +7 -0
  527. data/spec/dummy/app/assets/javascripts/application.js +8 -0
  528. data/spec/dummy/app/assets/stylesheets/application.css +8 -0
  529. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  530. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  531. data/spec/dummy/config.ru +4 -0
  532. data/spec/dummy/config/application.rb +44 -0
  533. data/spec/dummy/config/boot.rb +10 -0
  534. data/spec/dummy/config/database.yml +40 -0
  535. data/spec/dummy/config/environment.rb +5 -0
  536. data/spec/dummy/config/environments/development.rb +30 -0
  537. data/spec/dummy/config/environments/production.rb +54 -0
  538. data/spec/dummy/config/environments/test.rb +40 -0
  539. data/spec/dummy/config/environments/test_pg.rb +35 -0
  540. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  541. data/spec/dummy/config/initializers/devise.rb +220 -0
  542. data/spec/dummy/config/initializers/inflections.rb +10 -0
  543. data/spec/dummy/config/initializers/mailboxer.rb +8 -0
  544. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  545. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  546. data/spec/dummy/config/initializers/session_store.rb +8 -0
  547. data/spec/dummy/config/initializers/social_stream.rb +32 -0
  548. data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
  549. data/spec/dummy/config/locales/en.yml +5 -0
  550. data/spec/dummy/config/navigation.rb +4 -0
  551. data/spec/dummy/config/relations.yml +39 -0
  552. data/spec/dummy/config/routes.rb +60 -0
  553. data/spec/dummy/db/schema.rb +5 -0
  554. data/spec/dummy/db/seeds.rb +8 -0
  555. data/spec/dummy/public/404.html +26 -0
  556. data/spec/dummy/public/422.html +26 -0
  557. data/spec/dummy/public/500.html +26 -0
  558. data/spec/dummy/public/favicon.ico +0 -0
  559. data/spec/dummy/script/rails +6 -0
  560. data/spec/factories/activity.rb +52 -0
  561. data/spec/factories/comment.rb +6 -0
  562. data/spec/factories/contact.rb +16 -0
  563. data/spec/factories/group.rb +5 -0
  564. data/spec/factories/post.rb +11 -0
  565. data/spec/factories/relation_custom.rb +4 -0
  566. data/spec/factories/tie.rb +43 -0
  567. data/spec/factories/user.rb +6 -0
  568. data/spec/integration/navigation_spec.rb +33 -0
  569. data/spec/models/activity_authorization_spec.rb +350 -0
  570. data/spec/models/activity_spec.rb +131 -0
  571. data/spec/models/actor_spec.rb +80 -0
  572. data/spec/models/contact_spec.rb +53 -0
  573. data/spec/models/group_spec.rb +28 -0
  574. data/spec/models/like_spec.rb +68 -0
  575. data/spec/models/post_spec.rb +63 -0
  576. data/spec/models/profile_spec.rb +39 -0
  577. data/spec/models/relation_spec.rb +78 -0
  578. data/spec/models/tie_spec.rb +169 -0
  579. data/spec/models/user_spec.rb +109 -0
  580. data/spec/social_stream_spec.rb +7 -0
  581. data/spec/spec_helper.rb +26 -0
  582. data/spec/support/cancan.rb +1 -0
  583. data/spec/support/db.rb +7 -0
  584. data/spec/support/devise.rb +4 -0
  585. data/spec/support/mock.rb +4 -0
  586. data/vendor/assets/javascripts/ajax.paginate.js +46 -0
  587. data/vendor/assets/javascripts/d3.geom.js +825 -0
  588. data/vendor/assets/javascripts/d3.js +4013 -0
  589. data/vendor/assets/javascripts/d3.layout.js +1865 -0
  590. data/vendor/assets/javascripts/hoverIntent.js +84 -0
  591. data/vendor/assets/javascripts/jqcloud-0.1.3.js +87 -0
  592. data/vendor/assets/javascripts/jquery.ae.image.resize.js +69 -0
  593. data/vendor/assets/javascripts/jquery.ba-url.js +1091 -0
  594. data/vendor/assets/javascripts/jquery.cleditor.min.js +31 -0
  595. data/vendor/assets/javascripts/jquery.fcbkcomplete.js +553 -0
  596. data/vendor/assets/javascripts/jquery.lightbox-with-resize-plugin.js +533 -0
  597. data/vendor/assets/javascripts/jquery.livequery.js +250 -0
  598. data/vendor/assets/javascripts/jquery.screw.js +186 -0
  599. data/vendor/assets/javascripts/jquery.scrollTo.min.js +11 -0
  600. data/vendor/assets/javascripts/jquery.tipsy.js +263 -0
  601. data/vendor/assets/javascripts/jquery.validate.js +1166 -0
  602. data/vendor/assets/javascripts/jquery.validate.old.js +1132 -0
  603. data/vendor/assets/javascripts/jquery.watermarkinput.js +81 -0
  604. data/vendor/assets/javascripts/menu.js +25 -0
  605. data/vendor/assets/javascripts/superfish.js +121 -0
  606. data/vendor/assets/stylesheets/carousel.css +23 -0
  607. data/vendor/assets/stylesheets/chosen-sprite.png +0 -0
  608. data/vendor/assets/stylesheets/chosen.css +317 -0
  609. data/vendor/assets/stylesheets/fcbkComplete.css +44 -0
  610. data/vendor/assets/stylesheets/jqcloud.css +15 -0
  611. data/vendor/assets/stylesheets/jquery-ui.css +620 -0
  612. data/vendor/assets/stylesheets/jquery.cleditor.css +24 -0
  613. data/vendor/assets/stylesheets/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  614. data/vendor/assets/stylesheets/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  615. data/vendor/assets/stylesheets/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  616. data/vendor/assets/stylesheets/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  617. data/vendor/assets/stylesheets/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  618. data/vendor/assets/stylesheets/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  619. data/vendor/assets/stylesheets/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  620. data/vendor/assets/stylesheets/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  621. data/vendor/assets/stylesheets/smoothness/images/ui-icons_222222_256x240.png +0 -0
  622. data/vendor/assets/stylesheets/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  623. data/vendor/assets/stylesheets/smoothness/images/ui-icons_454545_256x240.png +0 -0
  624. data/vendor/assets/stylesheets/smoothness/images/ui-icons_888888_256x240.png +0 -0
  625. data/vendor/assets/stylesheets/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  626. data/vendor/assets/stylesheets/smoothness/jquery-ui-1.7.3.custom.css +405 -0
  627. data/vendor/assets/stylesheets/smoothness/jquery-ui-1.8.4.custom.css +572 -0
  628. data/vendor/assets/stylesheets/tipsy.css +25 -0
  629. metadata +997 -0
@@ -0,0 +1,4013 @@
1
+ (function(){if (!Date.now) Date.now = function() {
2
+ return +new Date;
3
+ };
4
+ try {
5
+ document.createElement("div").style.setProperty("opacity", 0, "");
6
+ } catch (error) {
7
+ var d3_style_prototype = CSSStyleDeclaration.prototype,
8
+ d3_style_setProperty = d3_style_prototype.setProperty;
9
+ d3_style_prototype.setProperty = function(name, value, priority) {
10
+ d3_style_setProperty.call(this, name, value + "", priority);
11
+ };
12
+ }
13
+ d3 = {version: "2.1.2"}; // semver
14
+ var d3_arraySubclass = [].__proto__?
15
+
16
+ // Until ECMAScript supports array subclassing, prototype injection works well.
17
+ function(array, prototype) {
18
+ array.__proto__ = prototype;
19
+ }:
20
+
21
+ // And if your browser doesn't support __proto__, we'll use direct extension.
22
+ function(array, prototype) {
23
+ for (var property in prototype) array[property] = prototype[property];
24
+ };
25
+ function d3_this() {
26
+ return this;
27
+ }
28
+ d3.functor = function(v) {
29
+ return typeof v === "function" ? v : function() { return v; };
30
+ };
31
+ // A getter-setter method that preserves the appropriate `this` context.
32
+ d3.rebind = function(object, method) {
33
+ return function() {
34
+ var x = method.apply(object, arguments);
35
+ return arguments.length ? object : x;
36
+ };
37
+ };
38
+ d3.ascending = function(a, b) {
39
+ return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
40
+ };
41
+ d3.descending = function(a, b) {
42
+ return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
43
+ };
44
+ d3.min = function(array, f) {
45
+ var i = -1,
46
+ n = array.length,
47
+ a,
48
+ b;
49
+ if (arguments.length === 1) {
50
+ while (++i < n && ((a = array[i]) == null || a != a)) a = undefined;
51
+ while (++i < n) if ((b = array[i]) != null && a > b) a = b;
52
+ } else {
53
+ while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined;
54
+ while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
55
+ }
56
+ return a;
57
+ };
58
+ d3.max = function(array, f) {
59
+ var i = -1,
60
+ n = array.length,
61
+ a,
62
+ b;
63
+ if (arguments.length === 1) {
64
+ while (++i < n && ((a = array[i]) == null || a != a)) a = undefined;
65
+ while (++i < n) if ((b = array[i]) != null && b > a) a = b;
66
+ } else {
67
+ while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined;
68
+ while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;
69
+ }
70
+ return a;
71
+ };
72
+ d3.sum = function(array, f) {
73
+ var s = 0,
74
+ n = array.length,
75
+ a,
76
+ i = -1;
77
+
78
+ if (arguments.length === 1) {
79
+ while (++i < n) if (!isNaN(a = +array[i])) s += a;
80
+ } else {
81
+ while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a;
82
+ }
83
+
84
+ return s;
85
+ };
86
+ // R-7 per <http://en.wikipedia.org/wiki/Quantile>
87
+ d3.quantile = function(values, p) {
88
+ var H = (values.length - 1) * p + 1,
89
+ h = Math.floor(H),
90
+ v = values[h - 1],
91
+ e = H - h;
92
+ return e ? v + e * (values[h] - v) : v;
93
+ };
94
+ d3.zip = function() {
95
+ if (!(n = arguments.length)) return [];
96
+ for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m;) {
97
+ for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n;) {
98
+ zip[j] = arguments[j][i];
99
+ }
100
+ }
101
+ return zips;
102
+ };
103
+
104
+ function d3_zipLength(d) {
105
+ return d.length;
106
+ }
107
+ // Locate the insertion point for x in a to maintain sorted order. The
108
+ // arguments lo and hi may be used to specify a subset of the array which should
109
+ // be considered; by default the entire array is used. If x is already present
110
+ // in a, the insertion point will be before (to the left of) any existing
111
+ // entries. The return value is suitable for use as the first argument to
112
+ // `array.splice` assuming that a is already sorted.
113
+ //
114
+ // The returned insertion point i partitions the array a into two halves so that
115
+ // all v < x for v in a[lo:i] for the left side and all v >= x for v in a[i:hi]
116
+ // for the right side.
117
+ d3.bisectLeft = function(a, x, lo, hi) {
118
+ if (arguments.length < 3) lo = 0;
119
+ if (arguments.length < 4) hi = a.length;
120
+ while (lo < hi) {
121
+ var mid = (lo + hi) >> 1;
122
+ if (a[mid] < x) lo = mid + 1;
123
+ else hi = mid;
124
+ }
125
+ return lo;
126
+ };
127
+
128
+ // Similar to bisectLeft, but returns an insertion point which comes after (to
129
+ // the right of) any existing entries of x in a.
130
+ //
131
+ // The returned insertion point i partitions the array into two halves so that
132
+ // all v <= x for v in a[lo:i] for the left side and all v > x for v in a[i:hi]
133
+ // for the right side.
134
+ d3.bisect =
135
+ d3.bisectRight = function(a, x, lo, hi) {
136
+ if (arguments.length < 3) lo = 0;
137
+ if (arguments.length < 4) hi = a.length;
138
+ while (lo < hi) {
139
+ var mid = (lo + hi) >> 1;
140
+ if (x < a[mid]) hi = mid;
141
+ else lo = mid + 1;
142
+ }
143
+ return lo;
144
+ };
145
+ d3.first = function(array, f) {
146
+ var i = 0,
147
+ n = array.length,
148
+ a = array[0],
149
+ b;
150
+ if (arguments.length === 1) f = d3.ascending;
151
+ while (++i < n) {
152
+ if (f.call(array, a, b = array[i]) > 0) {
153
+ a = b;
154
+ }
155
+ }
156
+ return a;
157
+ };
158
+ d3.last = function(array, f) {
159
+ var i = 0,
160
+ n = array.length,
161
+ a = array[0],
162
+ b;
163
+ if (arguments.length === 1) f = d3.ascending;
164
+ while (++i < n) {
165
+ if (f.call(array, a, b = array[i]) <= 0) {
166
+ a = b;
167
+ }
168
+ }
169
+ return a;
170
+ };
171
+ d3.nest = function() {
172
+ var nest = {},
173
+ keys = [],
174
+ sortKeys = [],
175
+ sortValues,
176
+ rollup;
177
+
178
+ function map(array, depth) {
179
+ if (depth >= keys.length) return rollup
180
+ ? rollup.call(nest, array) : (sortValues
181
+ ? array.sort(sortValues)
182
+ : array);
183
+
184
+ var i = -1,
185
+ n = array.length,
186
+ key = keys[depth++],
187
+ keyValue,
188
+ object,
189
+ o = {};
190
+
191
+ while (++i < n) {
192
+ if ((keyValue = key(object = array[i])) in o) {
193
+ o[keyValue].push(object);
194
+ } else {
195
+ o[keyValue] = [object];
196
+ }
197
+ }
198
+
199
+ for (keyValue in o) {
200
+ o[keyValue] = map(o[keyValue], depth);
201
+ }
202
+
203
+ return o;
204
+ }
205
+
206
+ function entries(map, depth) {
207
+ if (depth >= keys.length) return map;
208
+
209
+ var a = [],
210
+ sortKey = sortKeys[depth++],
211
+ key;
212
+
213
+ for (key in map) {
214
+ a.push({key: key, values: entries(map[key], depth)});
215
+ }
216
+
217
+ if (sortKey) a.sort(function(a, b) {
218
+ return sortKey(a.key, b.key);
219
+ });
220
+
221
+ return a;
222
+ }
223
+
224
+ nest.map = function(array) {
225
+ return map(array, 0);
226
+ };
227
+
228
+ nest.entries = function(array) {
229
+ return entries(map(array, 0), 0);
230
+ };
231
+
232
+ nest.key = function(d) {
233
+ keys.push(d);
234
+ return nest;
235
+ };
236
+
237
+ // Specifies the order for the most-recently specified key.
238
+ // Note: only applies to entries. Map keys are unordered!
239
+ nest.sortKeys = function(order) {
240
+ sortKeys[keys.length - 1] = order;
241
+ return nest;
242
+ };
243
+
244
+ // Specifies the order for leaf values.
245
+ // Applies to both maps and entries array.
246
+ nest.sortValues = function(order) {
247
+ sortValues = order;
248
+ return nest;
249
+ };
250
+
251
+ nest.rollup = function(f) {
252
+ rollup = f;
253
+ return nest;
254
+ };
255
+
256
+ return nest;
257
+ };
258
+ d3.keys = function(map) {
259
+ var keys = [];
260
+ for (var key in map) keys.push(key);
261
+ return keys;
262
+ };
263
+ d3.values = function(map) {
264
+ var values = [];
265
+ for (var key in map) values.push(map[key]);
266
+ return values;
267
+ };
268
+ d3.entries = function(map) {
269
+ var entries = [];
270
+ for (var key in map) entries.push({key: key, value: map[key]});
271
+ return entries;
272
+ };
273
+ d3.permute = function(array, indexes) {
274
+ var permutes = [],
275
+ i = -1,
276
+ n = indexes.length;
277
+ while (++i < n) permutes[i] = array[indexes[i]];
278
+ return permutes;
279
+ };
280
+ d3.merge = function(arrays) {
281
+ return Array.prototype.concat.apply([], arrays);
282
+ };
283
+ d3.split = function(array, f) {
284
+ var arrays = [],
285
+ values = [],
286
+ value,
287
+ i = -1,
288
+ n = array.length;
289
+ if (arguments.length < 2) f = d3_splitter;
290
+ while (++i < n) {
291
+ if (f.call(values, value = array[i], i)) {
292
+ values = [];
293
+ } else {
294
+ if (!values.length) arrays.push(values);
295
+ values.push(value);
296
+ }
297
+ }
298
+ return arrays;
299
+ };
300
+
301
+ function d3_splitter(d) {
302
+ return d == null;
303
+ }
304
+ function d3_collapse(s) {
305
+ return s.replace(/(^\s+)|(\s+$)/g, "").replace(/\s+/g, " ");
306
+ }
307
+ /**
308
+ * @param {number} start
309
+ * @param {number=} stop
310
+ * @param {number=} step
311
+ */
312
+ d3.range = function(start, stop, step) {
313
+ if (arguments.length < 3) {
314
+ step = 1;
315
+ if (arguments.length < 2) {
316
+ stop = start;
317
+ start = 0;
318
+ }
319
+ }
320
+ if ((stop - start) / step == Infinity) throw new Error("infinite range");
321
+ var range = [],
322
+ i = -1,
323
+ j;
324
+ if (step < 0) while ((j = start + step * ++i) > stop) range.push(j);
325
+ else while ((j = start + step * ++i) < stop) range.push(j);
326
+ return range;
327
+ };
328
+ d3.requote = function(s) {
329
+ return s.replace(d3_requote_re, "\\$&");
330
+ };
331
+
332
+ var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
333
+ d3.round = function(x, n) {
334
+ return n
335
+ ? Math.round(x * Math.pow(10, n)) * Math.pow(10, -n)
336
+ : Math.round(x);
337
+ };
338
+ d3.xhr = function(url, mime, callback) {
339
+ var req = new XMLHttpRequest;
340
+ if (arguments.length < 3) callback = mime;
341
+ else if (mime && req.overrideMimeType) req.overrideMimeType(mime);
342
+ req.open("GET", url, true);
343
+ req.onreadystatechange = function() {
344
+ if (req.readyState === 4) callback(req.status < 300 ? req : null);
345
+ };
346
+ req.send(null);
347
+ };
348
+ d3.text = function(url, mime, callback) {
349
+ function ready(req) {
350
+ callback(req && req.responseText);
351
+ }
352
+ if (arguments.length < 3) {
353
+ callback = mime;
354
+ mime = null;
355
+ }
356
+ d3.xhr(url, mime, ready);
357
+ };
358
+ d3.json = function(url, callback) {
359
+ d3.text(url, "application/json", function(text) {
360
+ callback(text ? JSON.parse(text) : null);
361
+ });
362
+ };
363
+ d3.html = function(url, callback) {
364
+ d3.text(url, "text/html", function(text) {
365
+ if (text != null) { // Treat empty string as valid HTML.
366
+ var range = document.createRange();
367
+ range.selectNode(document.body);
368
+ text = range.createContextualFragment(text);
369
+ }
370
+ callback(text);
371
+ });
372
+ };
373
+ d3.xml = function(url, mime, callback) {
374
+ function ready(req) {
375
+ callback(req && req.responseXML);
376
+ }
377
+ if (arguments.length < 3) {
378
+ callback = mime;
379
+ mime = null;
380
+ }
381
+ d3.xhr(url, mime, ready);
382
+ };
383
+ d3.ns = {
384
+
385
+ prefix: {
386
+ svg: "http://www.w3.org/2000/svg",
387
+ xhtml: "http://www.w3.org/1999/xhtml",
388
+ xlink: "http://www.w3.org/1999/xlink",
389
+ xml: "http://www.w3.org/XML/1998/namespace",
390
+ xmlns: "http://www.w3.org/2000/xmlns/"
391
+ },
392
+
393
+ qualify: function(name) {
394
+ var i = name.indexOf(":");
395
+ return i < 0 ? name : {
396
+ space: d3.ns.prefix[name.substring(0, i)],
397
+ local: name.substring(i + 1)
398
+ };
399
+ }
400
+
401
+ };
402
+ /** @param {...string} types */
403
+ d3.dispatch = function(types) {
404
+ var dispatch = {},
405
+ type;
406
+ for (var i = 0, n = arguments.length; i < n; i++) {
407
+ type = arguments[i];
408
+ dispatch[type] = d3_dispatch(type);
409
+ }
410
+ return dispatch;
411
+ };
412
+
413
+ function d3_dispatch(type) {
414
+ var dispatch = {},
415
+ listeners = [];
416
+
417
+ dispatch.add = function(listener) {
418
+ for (var i = 0; i < listeners.length; i++) {
419
+ if (listeners[i].listener == listener) return dispatch; // already registered
420
+ }
421
+ listeners.push({listener: listener, on: true});
422
+ return dispatch;
423
+ };
424
+
425
+ dispatch.remove = function(listener) {
426
+ for (var i = 0; i < listeners.length; i++) {
427
+ var l = listeners[i];
428
+ if (l.listener == listener) {
429
+ l.on = false;
430
+ listeners = listeners.slice(0, i).concat(listeners.slice(i + 1));
431
+ break;
432
+ }
433
+ }
434
+ return dispatch;
435
+ };
436
+
437
+ dispatch.dispatch = function() {
438
+ var ls = listeners; // defensive reference
439
+ for (var i = 0, n = ls.length; i < n; i++) {
440
+ var l = ls[i];
441
+ if (l.on) l.listener.apply(this, arguments);
442
+ }
443
+ };
444
+
445
+ return dispatch;
446
+ };
447
+ // TODO align
448
+ d3.format = function(specifier) {
449
+ var match = d3_format_re.exec(specifier),
450
+ fill = match[1] || " ",
451
+ sign = match[3] || "",
452
+ zfill = match[5],
453
+ width = +match[6],
454
+ comma = match[7],
455
+ precision = match[8],
456
+ type = match[9],
457
+ percentage = false,
458
+ integer = false;
459
+
460
+ if (precision) precision = precision.substring(1);
461
+
462
+ if (zfill) {
463
+ fill = "0"; // TODO align = "=";
464
+ if (comma) width -= Math.floor((width - 1) / 4);
465
+ }
466
+
467
+ switch (type) {
468
+ case "n": comma = true; type = "g"; break;
469
+ case "%": percentage = true; type = "f"; break;
470
+ case "p": percentage = true; type = "r"; break;
471
+ case "d": integer = true; precision = "0"; break;
472
+ }
473
+
474
+ type = d3_format_types[type] || d3_format_typeDefault;
475
+
476
+ return function(value) {
477
+ var number = percentage ? value * 100 : +value,
478
+ negative = (number < 0) && (number = -number) ? "\u2212" : sign;
479
+
480
+ // Return the empty string for floats formatted as ints.
481
+ if (integer && (number % 1)) return "";
482
+
483
+ // Convert the input value to the desired precision.
484
+ value = type(number, precision);
485
+
486
+ // If the fill character is 0, the sign and group is applied after the fill.
487
+ if (zfill) {
488
+ var length = value.length + negative.length;
489
+ if (length < width) value = new Array(width - length + 1).join(fill) + value;
490
+ if (comma) value = d3_format_group(value);
491
+ value = negative + value;
492
+ }
493
+
494
+ // Otherwise (e.g., space-filling), the sign and group is applied before.
495
+ else {
496
+ if (comma) value = d3_format_group(value);
497
+ value = negative + value;
498
+ var length = value.length;
499
+ if (length < width) value = new Array(width - length + 1).join(fill) + value;
500
+ }
501
+ if (percentage) value += "%";
502
+
503
+ return value;
504
+ };
505
+ };
506
+
507
+ // [[fill]align][sign][#][0][width][,][.precision][type]
508
+ var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/;
509
+
510
+ var d3_format_types = {
511
+ g: function(x, p) { return x.toPrecision(p); },
512
+ e: function(x, p) { return x.toExponential(p); },
513
+ f: function(x, p) { return x.toFixed(p); },
514
+ r: function(x, p) {
515
+ var n = 1 + Math.floor(1e-15 + Math.log(x) / Math.LN10);
516
+ return d3.round(x, p - n).toFixed(Math.max(0, Math.min(20, p - n)));
517
+ }
518
+ };
519
+
520
+ function d3_format_typeDefault(x) {
521
+ return x + "";
522
+ }
523
+
524
+ // Apply comma grouping for thousands.
525
+ function d3_format_group(value) {
526
+ var i = value.lastIndexOf("."),
527
+ f = i >= 0 ? value.substring(i) : (i = value.length, ""),
528
+ t = [];
529
+ while (i > 0) t.push(value.substring(i -= 3, i + 3));
530
+ return t.reverse().join(",") + f;
531
+ }
532
+ /*
533
+ * TERMS OF USE - EASING EQUATIONS
534
+ *
535
+ * Open source under the BSD License.
536
+ *
537
+ * Copyright 2001 Robert Penner
538
+ * All rights reserved.
539
+ *
540
+ * Redistribution and use in source and binary forms, with or without
541
+ * modification, are permitted provided that the following conditions are met:
542
+ *
543
+ * - Redistributions of source code must retain the above copyright notice, this
544
+ * list of conditions and the following disclaimer.
545
+ *
546
+ * - Redistributions in binary form must reproduce the above copyright notice,
547
+ * this list of conditions and the following disclaimer in the documentation
548
+ * and/or other materials provided with the distribution.
549
+ *
550
+ * - Neither the name of the author nor the names of contributors may be used to
551
+ * endorse or promote products derived from this software without specific
552
+ * prior written permission.
553
+ *
554
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
555
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
556
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
557
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
558
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
559
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
560
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
561
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
562
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
563
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
564
+ * POSSIBILITY OF SUCH DAMAGE.
565
+ */
566
+
567
+ var d3_ease_quad = d3_ease_poly(2),
568
+ d3_ease_cubic = d3_ease_poly(3);
569
+
570
+ var d3_ease = {
571
+ linear: function() { return d3_ease_linear; },
572
+ poly: d3_ease_poly,
573
+ quad: function() { return d3_ease_quad; },
574
+ cubic: function() { return d3_ease_cubic; },
575
+ sin: function() { return d3_ease_sin; },
576
+ exp: function() { return d3_ease_exp; },
577
+ circle: function() { return d3_ease_circle; },
578
+ elastic: d3_ease_elastic,
579
+ back: d3_ease_back,
580
+ bounce: function() { return d3_ease_bounce; }
581
+ };
582
+
583
+ var d3_ease_mode = {
584
+ "in": function(f) { return f; },
585
+ "out": d3_ease_reverse,
586
+ "in-out": d3_ease_reflect,
587
+ "out-in": function(f) { return d3_ease_reflect(d3_ease_reverse(f)); }
588
+ };
589
+
590
+ d3.ease = function(name) {
591
+ var i = name.indexOf("-"),
592
+ t = i >= 0 ? name.substring(0, i) : name,
593
+ m = i >= 0 ? name.substring(i + 1) : "in";
594
+ return d3_ease_clamp(d3_ease_mode[m](d3_ease[t].apply(null, Array.prototype.slice.call(arguments, 1))));
595
+ };
596
+
597
+ function d3_ease_clamp(f) {
598
+ return function(t) {
599
+ return t <= 0 ? 0 : t >= 1 ? 1 : f(t);
600
+ };
601
+ }
602
+
603
+ function d3_ease_reverse(f) {
604
+ return function(t) {
605
+ return 1 - f(1 - t);
606
+ };
607
+ }
608
+
609
+ function d3_ease_reflect(f) {
610
+ return function(t) {
611
+ return .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t)));
612
+ };
613
+ }
614
+
615
+ function d3_ease_linear(t) {
616
+ return t;
617
+ }
618
+
619
+ function d3_ease_poly(e) {
620
+ return function(t) {
621
+ return Math.pow(t, e);
622
+ }
623
+ }
624
+
625
+ function d3_ease_sin(t) {
626
+ return 1 - Math.cos(t * Math.PI / 2);
627
+ }
628
+
629
+ function d3_ease_exp(t) {
630
+ return Math.pow(2, 10 * (t - 1));
631
+ }
632
+
633
+ function d3_ease_circle(t) {
634
+ return 1 - Math.sqrt(1 - t * t);
635
+ }
636
+
637
+ function d3_ease_elastic(a, p) {
638
+ var s;
639
+ if (arguments.length < 2) p = 0.45;
640
+ if (arguments.length < 1) { a = 1; s = p / 4; }
641
+ else s = p / (2 * Math.PI) * Math.asin(1 / a);
642
+ return function(t) {
643
+ return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * Math.PI / p);
644
+ };
645
+ }
646
+
647
+ function d3_ease_back(s) {
648
+ if (!s) s = 1.70158;
649
+ return function(t) {
650
+ return t * t * ((s + 1) * t - s);
651
+ };
652
+ }
653
+
654
+ function d3_ease_bounce(t) {
655
+ return t < 1 / 2.75 ? 7.5625 * t * t
656
+ : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75
657
+ : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375
658
+ : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
659
+ }
660
+ d3.event = null;
661
+ d3.interpolate = function(a, b) {
662
+ var i = d3.interpolators.length, f;
663
+ while (--i >= 0 && !(f = d3.interpolators[i](a, b)));
664
+ return f;
665
+ };
666
+
667
+ d3.interpolateNumber = function(a, b) {
668
+ b -= a;
669
+ return function(t) { return a + b * t; };
670
+ };
671
+
672
+ d3.interpolateRound = function(a, b) {
673
+ b -= a;
674
+ return function(t) { return Math.round(a + b * t); };
675
+ };
676
+
677
+ d3.interpolateString = function(a, b) {
678
+ var m, // current match
679
+ i, // current index
680
+ j, // current index (for coallescing)
681
+ s0 = 0, // start index of current string prefix
682
+ s1 = 0, // end index of current string prefix
683
+ s = [], // string constants and placeholders
684
+ q = [], // number interpolators
685
+ n, // q.length
686
+ o;
687
+
688
+ // Reset our regular expression!
689
+ d3_interpolate_number.lastIndex = 0;
690
+
691
+ // Find all numbers in b.
692
+ for (i = 0; m = d3_interpolate_number.exec(b); ++i) {
693
+ if (m.index) s.push(b.substring(s0, s1 = m.index));
694
+ q.push({i: s.length, x: m[0]});
695
+ s.push(null);
696
+ s0 = d3_interpolate_number.lastIndex;
697
+ }
698
+ if (s0 < b.length) s.push(b.substring(s0));
699
+
700
+ // Find all numbers in a.
701
+ for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) {
702
+ o = q[i];
703
+ if (o.x == m[0]) { // The numbers match, so coallesce.
704
+ if (o.i) {
705
+ if (s[o.i + 1] == null) { // This match is followed by another number.
706
+ s[o.i - 1] += o.x;
707
+ s.splice(o.i, 1);
708
+ for (j = i + 1; j < n; ++j) q[j].i--;
709
+ } else { // This match is followed by a string, so coallesce twice.
710
+ s[o.i - 1] += o.x + s[o.i + 1];
711
+ s.splice(o.i, 2);
712
+ for (j = i + 1; j < n; ++j) q[j].i -= 2;
713
+ }
714
+ } else {
715
+ if (s[o.i + 1] == null) { // This match is followed by another number.
716
+ s[o.i] = o.x;
717
+ } else { // This match is followed by a string, so coallesce twice.
718
+ s[o.i] = o.x + s[o.i + 1];
719
+ s.splice(o.i + 1, 1);
720
+ for (j = i + 1; j < n; ++j) q[j].i--;
721
+ }
722
+ }
723
+ q.splice(i, 1);
724
+ n--;
725
+ i--;
726
+ } else {
727
+ o.x = d3.interpolateNumber(parseFloat(m[0]), parseFloat(o.x));
728
+ }
729
+ }
730
+
731
+ // Remove any numbers in b not found in a.
732
+ while (i < n) {
733
+ o = q.pop();
734
+ if (s[o.i + 1] == null) { // This match is followed by another number.
735
+ s[o.i] = o.x;
736
+ } else { // This match is followed by a string, so coallesce twice.
737
+ s[o.i] = o.x + s[o.i + 1];
738
+ s.splice(o.i + 1, 1);
739
+ }
740
+ n--;
741
+ }
742
+
743
+ // Special optimization for only a single match.
744
+ if (s.length === 1) {
745
+ return s[0] == null ? q[0].x : function() { return b; };
746
+ }
747
+
748
+ // Otherwise, interpolate each of the numbers and rejoin the string.
749
+ return function(t) {
750
+ for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t);
751
+ return s.join("");
752
+ };
753
+ };
754
+
755
+ d3.interpolateRgb = function(a, b) {
756
+ a = d3.rgb(a);
757
+ b = d3.rgb(b);
758
+ var ar = a.r,
759
+ ag = a.g,
760
+ ab = a.b,
761
+ br = b.r - ar,
762
+ bg = b.g - ag,
763
+ bb = b.b - ab;
764
+ return function(t) {
765
+ return "rgb(" + Math.round(ar + br * t)
766
+ + "," + Math.round(ag + bg * t)
767
+ + "," + Math.round(ab + bb * t)
768
+ + ")";
769
+ };
770
+ };
771
+
772
+ // interpolates HSL space, but outputs RGB string (for compatibility)
773
+ d3.interpolateHsl = function(a, b) {
774
+ a = d3.hsl(a);
775
+ b = d3.hsl(b);
776
+ var h0 = a.h,
777
+ s0 = a.s,
778
+ l0 = a.l,
779
+ h1 = b.h - h0,
780
+ s1 = b.s - s0,
781
+ l1 = b.l - l0;
782
+ return function(t) {
783
+ return d3_hsl_rgb(h0 + h1 * t, s0 + s1 * t, l0 + l1 * t).toString();
784
+ };
785
+ };
786
+
787
+ d3.interpolateArray = function(a, b) {
788
+ var x = [],
789
+ c = [],
790
+ na = a.length,
791
+ nb = b.length,
792
+ n0 = Math.min(a.length, b.length),
793
+ i;
794
+ for (i = 0; i < n0; ++i) x.push(d3.interpolate(a[i], b[i]));
795
+ for (; i < na; ++i) c[i] = a[i];
796
+ for (; i < nb; ++i) c[i] = b[i];
797
+ return function(t) {
798
+ for (i = 0; i < n0; ++i) c[i] = x[i](t);
799
+ return c;
800
+ };
801
+ };
802
+
803
+ d3.interpolateObject = function(a, b) {
804
+ var i = {},
805
+ c = {},
806
+ k;
807
+ for (k in a) {
808
+ if (k in b) {
809
+ i[k] = d3_interpolateByName(k)(a[k], b[k]);
810
+ } else {
811
+ c[k] = a[k];
812
+ }
813
+ }
814
+ for (k in b) {
815
+ if (!(k in a)) {
816
+ c[k] = b[k];
817
+ }
818
+ }
819
+ return function(t) {
820
+ for (k in i) c[k] = i[k](t);
821
+ return c;
822
+ };
823
+ }
824
+
825
+ var d3_interpolate_number = /[-+]?(?:\d+\.\d+|\d+\.|\.\d+|\d+)(?:[eE][-]?\d+)?/g,
826
+ d3_interpolate_rgb = {background: 1, fill: 1, stroke: 1};
827
+
828
+ function d3_interpolateByName(n) {
829
+ return n in d3_interpolate_rgb || /\bcolor\b/.test(n)
830
+ ? d3.interpolateRgb
831
+ : d3.interpolate;
832
+ }
833
+
834
+ d3.interpolators = [
835
+ d3.interpolateObject,
836
+ function(a, b) { return (b instanceof Array) && d3.interpolateArray(a, b); },
837
+ function(a, b) { return (typeof b === "string") && d3.interpolateString(String(a), b); },
838
+ function(a, b) { return (typeof b === "string" ? b in d3_rgb_names || /^(#|rgb\(|hsl\()/.test(b) : b instanceof d3_Rgb || b instanceof d3_Hsl) && d3.interpolateRgb(String(a), b); },
839
+ function(a, b) { return (typeof b === "number") && d3.interpolateNumber(+a, b); }
840
+ ];
841
+ function d3_uninterpolateNumber(a, b) {
842
+ b = b - (a = +a) ? 1 / (b - a) : 0;
843
+ return function(x) { return (x - a) * b; };
844
+ }
845
+
846
+ function d3_uninterpolateClamp(a, b) {
847
+ b = b - (a = +a) ? 1 / (b - a) : 0;
848
+ return function(x) { return Math.max(0, Math.min(1, (x - a) * b)); };
849
+ }
850
+ d3.rgb = function(r, g, b) {
851
+ return arguments.length === 1
852
+ ? d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb)
853
+ : d3_rgb(~~r, ~~g, ~~b);
854
+ };
855
+
856
+ function d3_rgb(r, g, b) {
857
+ return new d3_Rgb(r, g, b);
858
+ }
859
+
860
+ function d3_Rgb(r, g, b) {
861
+ this.r = r;
862
+ this.g = g;
863
+ this.b = b;
864
+ }
865
+
866
+ d3_Rgb.prototype.brighter = function(k) {
867
+ k = Math.pow(0.7, arguments.length ? k : 1);
868
+ var r = this.r,
869
+ g = this.g,
870
+ b = this.b,
871
+ i = 30;
872
+ if (!r && !g && !b) return d3_rgb(i, i, i);
873
+ if (r && r < i) r = i;
874
+ if (g && g < i) g = i;
875
+ if (b && b < i) b = i;
876
+ return d3_rgb(
877
+ Math.min(255, Math.floor(r / k)),
878
+ Math.min(255, Math.floor(g / k)),
879
+ Math.min(255, Math.floor(b / k)));
880
+ };
881
+
882
+ d3_Rgb.prototype.darker = function(k) {
883
+ k = Math.pow(0.7, arguments.length ? k : 1);
884
+ return d3_rgb(
885
+ Math.max(0, Math.floor(k * this.r)),
886
+ Math.max(0, Math.floor(k * this.g)),
887
+ Math.max(0, Math.floor(k * this.b)));
888
+ };
889
+
890
+ d3_Rgb.prototype.hsl = function() {
891
+ return d3_rgb_hsl(this.r, this.g, this.b);
892
+ };
893
+
894
+ d3_Rgb.prototype.toString = function() {
895
+ return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);
896
+ };
897
+
898
+ function d3_rgb_hex(v) {
899
+ return v < 0x10 ? "0" + v.toString(16) : v.toString(16);
900
+ }
901
+
902
+ function d3_rgb_parse(format, rgb, hsl) {
903
+ var r = 0, // red channel; int in [0, 255]
904
+ g = 0, // green channel; int in [0, 255]
905
+ b = 0, // blue channel; int in [0, 255]
906
+ m1, // CSS color specification match
907
+ m2, // CSS color specification type (e.g., rgb)
908
+ name;
909
+
910
+ /* Handle hsl, rgb. */
911
+ m1 = /([a-z]+)\((.*)\)/i.exec(format);
912
+ if (m1) {
913
+ m2 = m1[2].split(",");
914
+ switch (m1[1]) {
915
+ case "hsl": {
916
+ return hsl(
917
+ parseFloat(m2[0]), // degrees
918
+ parseFloat(m2[1]) / 100, // percentage
919
+ parseFloat(m2[2]) / 100 // percentage
920
+ );
921
+ }
922
+ case "rgb": {
923
+ return rgb(
924
+ d3_rgb_parseNumber(m2[0]),
925
+ d3_rgb_parseNumber(m2[1]),
926
+ d3_rgb_parseNumber(m2[2])
927
+ );
928
+ }
929
+ }
930
+ }
931
+
932
+ /* Named colors. */
933
+ if (name = d3_rgb_names[format]) return rgb(name.r, name.g, name.b);
934
+
935
+ /* Hexadecimal colors: #rgb and #rrggbb. */
936
+ if (format != null && format.charAt(0) === "#") {
937
+ if (format.length === 4) {
938
+ r = format.charAt(1); r += r;
939
+ g = format.charAt(2); g += g;
940
+ b = format.charAt(3); b += b;
941
+ } else if (format.length === 7) {
942
+ r = format.substring(1, 3);
943
+ g = format.substring(3, 5);
944
+ b = format.substring(5, 7);
945
+ }
946
+ r = parseInt(r, 16);
947
+ g = parseInt(g, 16);
948
+ b = parseInt(b, 16);
949
+ }
950
+
951
+ return rgb(r, g, b);
952
+ }
953
+
954
+ function d3_rgb_hsl(r, g, b) {
955
+ var min = Math.min(r /= 255, g /= 255, b /= 255),
956
+ max = Math.max(r, g, b),
957
+ d = max - min,
958
+ h,
959
+ s,
960
+ l = (max + min) / 2;
961
+ if (d) {
962
+ s = l < .5 ? d / (max + min) : d / (2 - max - min);
963
+ if (r == max) h = (g - b) / d + (g < b ? 6 : 0);
964
+ else if (g == max) h = (b - r) / d + 2;
965
+ else h = (r - g) / d + 4;
966
+ h *= 60;
967
+ } else {
968
+ s = h = 0;
969
+ }
970
+ return d3_hsl(h, s, l);
971
+ }
972
+
973
+ function d3_rgb_parseNumber(c) { // either integer or percentage
974
+ var f = parseFloat(c);
975
+ return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
976
+ }
977
+
978
+ var d3_rgb_names = {
979
+ aliceblue: "#f0f8ff",
980
+ antiquewhite: "#faebd7",
981
+ aqua: "#00ffff",
982
+ aquamarine: "#7fffd4",
983
+ azure: "#f0ffff",
984
+ beige: "#f5f5dc",
985
+ bisque: "#ffe4c4",
986
+ black: "#000000",
987
+ blanchedalmond: "#ffebcd",
988
+ blue: "#0000ff",
989
+ blueviolet: "#8a2be2",
990
+ brown: "#a52a2a",
991
+ burlywood: "#deb887",
992
+ cadetblue: "#5f9ea0",
993
+ chartreuse: "#7fff00",
994
+ chocolate: "#d2691e",
995
+ coral: "#ff7f50",
996
+ cornflowerblue: "#6495ed",
997
+ cornsilk: "#fff8dc",
998
+ crimson: "#dc143c",
999
+ cyan: "#00ffff",
1000
+ darkblue: "#00008b",
1001
+ darkcyan: "#008b8b",
1002
+ darkgoldenrod: "#b8860b",
1003
+ darkgray: "#a9a9a9",
1004
+ darkgreen: "#006400",
1005
+ darkgrey: "#a9a9a9",
1006
+ darkkhaki: "#bdb76b",
1007
+ darkmagenta: "#8b008b",
1008
+ darkolivegreen: "#556b2f",
1009
+ darkorange: "#ff8c00",
1010
+ darkorchid: "#9932cc",
1011
+ darkred: "#8b0000",
1012
+ darksalmon: "#e9967a",
1013
+ darkseagreen: "#8fbc8f",
1014
+ darkslateblue: "#483d8b",
1015
+ darkslategray: "#2f4f4f",
1016
+ darkslategrey: "#2f4f4f",
1017
+ darkturquoise: "#00ced1",
1018
+ darkviolet: "#9400d3",
1019
+ deeppink: "#ff1493",
1020
+ deepskyblue: "#00bfff",
1021
+ dimgray: "#696969",
1022
+ dimgrey: "#696969",
1023
+ dodgerblue: "#1e90ff",
1024
+ firebrick: "#b22222",
1025
+ floralwhite: "#fffaf0",
1026
+ forestgreen: "#228b22",
1027
+ fuchsia: "#ff00ff",
1028
+ gainsboro: "#dcdcdc",
1029
+ ghostwhite: "#f8f8ff",
1030
+ gold: "#ffd700",
1031
+ goldenrod: "#daa520",
1032
+ gray: "#808080",
1033
+ green: "#008000",
1034
+ greenyellow: "#adff2f",
1035
+ grey: "#808080",
1036
+ honeydew: "#f0fff0",
1037
+ hotpink: "#ff69b4",
1038
+ indianred: "#cd5c5c",
1039
+ indigo: "#4b0082",
1040
+ ivory: "#fffff0",
1041
+ khaki: "#f0e68c",
1042
+ lavender: "#e6e6fa",
1043
+ lavenderblush: "#fff0f5",
1044
+ lawngreen: "#7cfc00",
1045
+ lemonchiffon: "#fffacd",
1046
+ lightblue: "#add8e6",
1047
+ lightcoral: "#f08080",
1048
+ lightcyan: "#e0ffff",
1049
+ lightgoldenrodyellow: "#fafad2",
1050
+ lightgray: "#d3d3d3",
1051
+ lightgreen: "#90ee90",
1052
+ lightgrey: "#d3d3d3",
1053
+ lightpink: "#ffb6c1",
1054
+ lightsalmon: "#ffa07a",
1055
+ lightseagreen: "#20b2aa",
1056
+ lightskyblue: "#87cefa",
1057
+ lightslategray: "#778899",
1058
+ lightslategrey: "#778899",
1059
+ lightsteelblue: "#b0c4de",
1060
+ lightyellow: "#ffffe0",
1061
+ lime: "#00ff00",
1062
+ limegreen: "#32cd32",
1063
+ linen: "#faf0e6",
1064
+ magenta: "#ff00ff",
1065
+ maroon: "#800000",
1066
+ mediumaquamarine: "#66cdaa",
1067
+ mediumblue: "#0000cd",
1068
+ mediumorchid: "#ba55d3",
1069
+ mediumpurple: "#9370db",
1070
+ mediumseagreen: "#3cb371",
1071
+ mediumslateblue: "#7b68ee",
1072
+ mediumspringgreen: "#00fa9a",
1073
+ mediumturquoise: "#48d1cc",
1074
+ mediumvioletred: "#c71585",
1075
+ midnightblue: "#191970",
1076
+ mintcream: "#f5fffa",
1077
+ mistyrose: "#ffe4e1",
1078
+ moccasin: "#ffe4b5",
1079
+ navajowhite: "#ffdead",
1080
+ navy: "#000080",
1081
+ oldlace: "#fdf5e6",
1082
+ olive: "#808000",
1083
+ olivedrab: "#6b8e23",
1084
+ orange: "#ffa500",
1085
+ orangered: "#ff4500",
1086
+ orchid: "#da70d6",
1087
+ palegoldenrod: "#eee8aa",
1088
+ palegreen: "#98fb98",
1089
+ paleturquoise: "#afeeee",
1090
+ palevioletred: "#db7093",
1091
+ papayawhip: "#ffefd5",
1092
+ peachpuff: "#ffdab9",
1093
+ peru: "#cd853f",
1094
+ pink: "#ffc0cb",
1095
+ plum: "#dda0dd",
1096
+ powderblue: "#b0e0e6",
1097
+ purple: "#800080",
1098
+ red: "#ff0000",
1099
+ rosybrown: "#bc8f8f",
1100
+ royalblue: "#4169e1",
1101
+ saddlebrown: "#8b4513",
1102
+ salmon: "#fa8072",
1103
+ sandybrown: "#f4a460",
1104
+ seagreen: "#2e8b57",
1105
+ seashell: "#fff5ee",
1106
+ sienna: "#a0522d",
1107
+ silver: "#c0c0c0",
1108
+ skyblue: "#87ceeb",
1109
+ slateblue: "#6a5acd",
1110
+ slategray: "#708090",
1111
+ slategrey: "#708090",
1112
+ snow: "#fffafa",
1113
+ springgreen: "#00ff7f",
1114
+ steelblue: "#4682b4",
1115
+ tan: "#d2b48c",
1116
+ teal: "#008080",
1117
+ thistle: "#d8bfd8",
1118
+ tomato: "#ff6347",
1119
+ turquoise: "#40e0d0",
1120
+ violet: "#ee82ee",
1121
+ wheat: "#f5deb3",
1122
+ white: "#ffffff",
1123
+ whitesmoke: "#f5f5f5",
1124
+ yellow: "#ffff00",
1125
+ yellowgreen: "#9acd32"
1126
+ };
1127
+
1128
+ for (var d3_rgb_name in d3_rgb_names) {
1129
+ d3_rgb_names[d3_rgb_name] = d3_rgb_parse(
1130
+ d3_rgb_names[d3_rgb_name],
1131
+ d3_rgb,
1132
+ d3_hsl_rgb);
1133
+ }
1134
+ d3.hsl = function(h, s, l) {
1135
+ return arguments.length === 1
1136
+ ? d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl)
1137
+ : d3_hsl(+h, +s, +l);
1138
+ };
1139
+
1140
+ function d3_hsl(h, s, l) {
1141
+ return new d3_Hsl(h, s, l);
1142
+ }
1143
+
1144
+ function d3_Hsl(h, s, l) {
1145
+ this.h = h;
1146
+ this.s = s;
1147
+ this.l = l;
1148
+ }
1149
+
1150
+ d3_Hsl.prototype.brighter = function(k) {
1151
+ k = Math.pow(0.7, arguments.length ? k : 1);
1152
+ return d3_hsl(this.h, this.s, this.l / k);
1153
+ };
1154
+
1155
+ d3_Hsl.prototype.darker = function(k) {
1156
+ k = Math.pow(0.7, arguments.length ? k : 1);
1157
+ return d3_hsl(this.h, this.s, k * this.l);
1158
+ };
1159
+
1160
+ d3_Hsl.prototype.rgb = function() {
1161
+ return d3_hsl_rgb(this.h, this.s, this.l);
1162
+ };
1163
+
1164
+ d3_Hsl.prototype.toString = function() {
1165
+ return "hsl(" + this.h + "," + this.s * 100 + "%," + this.l * 100 + "%)";
1166
+ };
1167
+
1168
+ function d3_hsl_rgb(h, s, l) {
1169
+ var m1,
1170
+ m2;
1171
+
1172
+ /* Some simple corrections for h, s and l. */
1173
+ h = h % 360; if (h < 0) h += 360;
1174
+ s = s < 0 ? 0 : s > 1 ? 1 : s;
1175
+ l = l < 0 ? 0 : l > 1 ? 1 : l;
1176
+
1177
+ /* From FvD 13.37, CSS Color Module Level 3 */
1178
+ m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
1179
+ m1 = 2 * l - m2;
1180
+
1181
+ function v(h) {
1182
+ if (h > 360) h -= 360;
1183
+ else if (h < 0) h += 360;
1184
+ if (h < 60) return m1 + (m2 - m1) * h / 60;
1185
+ if (h < 180) return m2;
1186
+ if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
1187
+ return m1;
1188
+ }
1189
+
1190
+ function vv(h) {
1191
+ return Math.round(v(h) * 255);
1192
+ }
1193
+
1194
+ return d3_rgb(vv(h + 120), vv(h), vv(h - 120));
1195
+ }
1196
+ function d3_selection(groups) {
1197
+ d3_arraySubclass(groups, d3_selectionPrototype);
1198
+ return groups;
1199
+ }
1200
+
1201
+ var d3_select = function(s, n) { return n.querySelector(s); },
1202
+ d3_selectAll = function(s, n) { return n.querySelectorAll(s); };
1203
+
1204
+ // Prefer Sizzle, if available.
1205
+ if (typeof Sizzle === "function") {
1206
+ d3_select = function(s, n) { return Sizzle(s, n)[0]; };
1207
+ d3_selectAll = function(s, n) { return Sizzle.uniqueSort(Sizzle(s, n)); };
1208
+ }
1209
+
1210
+ var d3_selectionPrototype = [];
1211
+
1212
+ d3.selection = function() {
1213
+ return d3_selectionRoot;
1214
+ };
1215
+
1216
+ d3.selection.prototype = d3_selectionPrototype;
1217
+ d3_selectionPrototype.select = function(selector) {
1218
+ var subgroups = [],
1219
+ subgroup,
1220
+ subnode,
1221
+ group,
1222
+ node;
1223
+
1224
+ if (typeof selector !== "function") selector = d3_selection_selector(selector);
1225
+
1226
+ for (var j = -1, m = this.length; ++j < m;) {
1227
+ subgroups.push(subgroup = []);
1228
+ subgroup.parentNode = (group = this[j]).parentNode;
1229
+ for (var i = -1, n = group.length; ++i < n;) {
1230
+ if (node = group[i]) {
1231
+ subgroup.push(subnode = selector.call(node, node.__data__, i));
1232
+ if (subnode && "__data__" in node) subnode.__data__ = node.__data__;
1233
+ } else {
1234
+ subgroup.push(null);
1235
+ }
1236
+ }
1237
+ }
1238
+
1239
+ return d3_selection(subgroups);
1240
+ };
1241
+
1242
+ function d3_selection_selector(selector) {
1243
+ return function() {
1244
+ return d3_select(selector, this);
1245
+ };
1246
+ }
1247
+ d3_selectionPrototype.selectAll = function(selector) {
1248
+ var subgroups = [],
1249
+ subgroup,
1250
+ node;
1251
+
1252
+ if (typeof selector !== "function") selector = d3_selection_selectorAll(selector);
1253
+
1254
+ for (var j = -1, m = this.length; ++j < m;) {
1255
+ for (var group = this[j], i = -1, n = group.length; ++i < n;) {
1256
+ if (node = group[i]) {
1257
+ subgroups.push(subgroup = selector.call(node, node.__data__, i));
1258
+ subgroup.parentNode = node;
1259
+ }
1260
+ }
1261
+ }
1262
+
1263
+ return d3_selection(subgroups);
1264
+ };
1265
+
1266
+ function d3_selection_selectorAll(selector) {
1267
+ return function() {
1268
+ return d3_selectAll(selector, this);
1269
+ };
1270
+ }
1271
+ d3_selectionPrototype.attr = function(name, value) {
1272
+ name = d3.ns.qualify(name);
1273
+
1274
+ // If no value is specified, return the first value.
1275
+ if (arguments.length < 2) {
1276
+ var node = this.node();
1277
+ return name.local
1278
+ ? node.getAttributeNS(name.space, name.local)
1279
+ : node.getAttribute(name);
1280
+ }
1281
+
1282
+ function attrNull() {
1283
+ this.removeAttribute(name);
1284
+ }
1285
+
1286
+ function attrNullNS() {
1287
+ this.removeAttributeNS(name.space, name.local);
1288
+ }
1289
+
1290
+ function attrConstant() {
1291
+ this.setAttribute(name, value);
1292
+ }
1293
+
1294
+ function attrConstantNS() {
1295
+ this.setAttributeNS(name.space, name.local, value);
1296
+ }
1297
+
1298
+ function attrFunction() {
1299
+ var x = value.apply(this, arguments);
1300
+ if (x == null) this.removeAttribute(name);
1301
+ else this.setAttribute(name, x);
1302
+ }
1303
+
1304
+ function attrFunctionNS() {
1305
+ var x = value.apply(this, arguments);
1306
+ if (x == null) this.removeAttributeNS(name.space, name.local);
1307
+ else this.setAttributeNS(name.space, name.local, x);
1308
+ }
1309
+
1310
+ return this.each(value == null
1311
+ ? (name.local ? attrNullNS : attrNull) : (typeof value === "function"
1312
+ ? (name.local ? attrFunctionNS : attrFunction)
1313
+ : (name.local ? attrConstantNS : attrConstant)));
1314
+ };
1315
+ d3_selectionPrototype.classed = function(name, value) {
1316
+ var re = new RegExp("(^|\\s+)" + d3.requote(name) + "(\\s+|$)", "g");
1317
+
1318
+ // If no value is specified, return the first value.
1319
+ if (arguments.length < 2) {
1320
+ var node = this.node();
1321
+ if (c = node.classList) return c.contains(name);
1322
+ var c = node.className;
1323
+ re.lastIndex = 0;
1324
+ return re.test(c.baseVal != null ? c.baseVal : c);
1325
+ }
1326
+
1327
+ function classedAdd() {
1328
+ if (c = this.classList) return c.add(name);
1329
+ var c = this.className,
1330
+ cb = c.baseVal != null,
1331
+ cv = cb ? c.baseVal : c;
1332
+ re.lastIndex = 0;
1333
+ if (!re.test(cv)) {
1334
+ cv = d3_collapse(cv + " " + name);
1335
+ if (cb) c.baseVal = cv;
1336
+ else this.className = cv;
1337
+ }
1338
+ }
1339
+
1340
+ function classedRemove() {
1341
+ if (c = this.classList) return c.remove(name);
1342
+ var c = this.className,
1343
+ cb = c.baseVal != null,
1344
+ cv = cb ? c.baseVal : c;
1345
+ cv = d3_collapse(cv.replace(re, " "));
1346
+ if (cb) c.baseVal = cv;
1347
+ else this.className = cv;
1348
+ }
1349
+
1350
+ function classedFunction() {
1351
+ (value.apply(this, arguments)
1352
+ ? classedAdd
1353
+ : classedRemove).call(this);
1354
+ }
1355
+
1356
+ return this.each(typeof value === "function"
1357
+ ? classedFunction : value
1358
+ ? classedAdd
1359
+ : classedRemove);
1360
+ };
1361
+ d3_selectionPrototype.style = function(name, value, priority) {
1362
+ if (arguments.length < 3) priority = "";
1363
+
1364
+ // If no value is specified, return the first value.
1365
+ if (arguments.length < 2) return window
1366
+ .getComputedStyle(this.node(), null)
1367
+ .getPropertyValue(name);
1368
+
1369
+ function styleNull() {
1370
+ this.style.removeProperty(name);
1371
+ }
1372
+
1373
+ function styleConstant() {
1374
+ this.style.setProperty(name, value, priority);
1375
+ }
1376
+
1377
+ function styleFunction() {
1378
+ var x = value.apply(this, arguments);
1379
+ if (x == null) this.style.removeProperty(name);
1380
+ else this.style.setProperty(name, x, priority);
1381
+ }
1382
+
1383
+ return this.each(value == null
1384
+ ? styleNull : (typeof value === "function"
1385
+ ? styleFunction : styleConstant));
1386
+ };
1387
+ d3_selectionPrototype.property = function(name, value) {
1388
+
1389
+ // If no value is specified, return the first value.
1390
+ if (arguments.length < 2) return this.node()[name];
1391
+
1392
+ function propertyNull() {
1393
+ delete this[name];
1394
+ }
1395
+
1396
+ function propertyConstant() {
1397
+ this[name] = value;
1398
+ }
1399
+
1400
+ function propertyFunction() {
1401
+ var x = value.apply(this, arguments);
1402
+ if (x == null) delete this[name];
1403
+ else this[name] = x;
1404
+ }
1405
+
1406
+ return this.each(value == null
1407
+ ? propertyNull : (typeof value === "function"
1408
+ ? propertyFunction : propertyConstant));
1409
+ };
1410
+ d3_selectionPrototype.text = function(value) {
1411
+ return arguments.length < 1 ? this.node().textContent
1412
+ : (this.each(typeof value === "function"
1413
+ ? function() { this.textContent = value.apply(this, arguments); }
1414
+ : function() { this.textContent = value; }));
1415
+ };
1416
+ d3_selectionPrototype.html = function(value) {
1417
+ return arguments.length < 1 ? this.node().innerHTML
1418
+ : (this.each(typeof value === "function"
1419
+ ? function() { this.innerHTML = value.apply(this, arguments); }
1420
+ : function() { this.innerHTML = value; }));
1421
+ };
1422
+ // TODO append(node)?
1423
+ // TODO append(function)?
1424
+ d3_selectionPrototype.append = function(name) {
1425
+ name = d3.ns.qualify(name);
1426
+
1427
+ function append() {
1428
+ return this.appendChild(document.createElement(name));
1429
+ }
1430
+
1431
+ function appendNS() {
1432
+ return this.appendChild(document.createElementNS(name.space, name.local));
1433
+ }
1434
+
1435
+ return this.select(name.local ? appendNS : append);
1436
+ };
1437
+ // TODO insert(node, function)?
1438
+ // TODO insert(function, string)?
1439
+ // TODO insert(function, function)?
1440
+ d3_selectionPrototype.insert = function(name, before) {
1441
+ name = d3.ns.qualify(name);
1442
+
1443
+ function insert() {
1444
+ return this.insertBefore(
1445
+ document.createElement(name),
1446
+ d3_select(before, this));
1447
+ }
1448
+
1449
+ function insertNS() {
1450
+ return this.insertBefore(
1451
+ document.createElementNS(name.space, name.local),
1452
+ d3_select(before, this));
1453
+ }
1454
+
1455
+ return this.select(name.local ? insertNS : insert);
1456
+ };
1457
+ // TODO remove(selector)?
1458
+ // TODO remove(node)?
1459
+ // TODO remove(function)?
1460
+ d3_selectionPrototype.remove = function() {
1461
+ return this.each(function() {
1462
+ var parent = this.parentNode;
1463
+ if (parent) parent.removeChild(this);
1464
+ });
1465
+ };
1466
+ // TODO data(null) for clearing data?
1467
+ d3_selectionPrototype.data = function(data, join) {
1468
+ var enter = [],
1469
+ update = [],
1470
+ exit = [];
1471
+
1472
+ function bind(group, groupData) {
1473
+ var i,
1474
+ n = group.length,
1475
+ m = groupData.length,
1476
+ n0 = Math.min(n, m),
1477
+ n1 = Math.max(n, m),
1478
+ updateNodes = [],
1479
+ enterNodes = [],
1480
+ exitNodes = [],
1481
+ node,
1482
+ nodeData;
1483
+
1484
+ if (join) {
1485
+ var nodeByKey = {},
1486
+ keys = [],
1487
+ key,
1488
+ j = groupData.length;
1489
+
1490
+ for (i = -1; ++i < n;) {
1491
+ key = join.call(node = group[i], node.__data__, i);
1492
+ if (key in nodeByKey) {
1493
+ exitNodes[j++] = node; // duplicate key
1494
+ } else {
1495
+ nodeByKey[key] = node;
1496
+ }
1497
+ keys.push(key);
1498
+ }
1499
+
1500
+ for (i = -1; ++i < m;) {
1501
+ node = nodeByKey[key = join.call(groupData, nodeData = groupData[i], i)];
1502
+ if (node) {
1503
+ node.__data__ = nodeData;
1504
+ updateNodes[i] = node;
1505
+ enterNodes[i] = exitNodes[i] = null;
1506
+ } else {
1507
+ enterNodes[i] = d3_selection_dataNode(nodeData);
1508
+ updateNodes[i] = exitNodes[i] = null;
1509
+ }
1510
+ delete nodeByKey[key];
1511
+ }
1512
+
1513
+ for (i = -1; ++i < n;) {
1514
+ if (keys[i] in nodeByKey) {
1515
+ exitNodes[i] = group[i];
1516
+ }
1517
+ }
1518
+ } else {
1519
+ for (i = -1; ++i < n0;) {
1520
+ node = group[i];
1521
+ nodeData = groupData[i];
1522
+ if (node) {
1523
+ node.__data__ = nodeData;
1524
+ updateNodes[i] = node;
1525
+ enterNodes[i] = exitNodes[i] = null;
1526
+ } else {
1527
+ enterNodes[i] = d3_selection_dataNode(nodeData);
1528
+ updateNodes[i] = exitNodes[i] = null;
1529
+ }
1530
+ }
1531
+ for (; i < m; ++i) {
1532
+ enterNodes[i] = d3_selection_dataNode(groupData[i]);
1533
+ updateNodes[i] = exitNodes[i] = null;
1534
+ }
1535
+ for (; i < n1; ++i) {
1536
+ exitNodes[i] = group[i];
1537
+ enterNodes[i] = updateNodes[i] = null;
1538
+ }
1539
+ }
1540
+
1541
+ enterNodes.update
1542
+ = updateNodes;
1543
+
1544
+ enterNodes.parentNode
1545
+ = updateNodes.parentNode
1546
+ = exitNodes.parentNode
1547
+ = group.parentNode;
1548
+
1549
+ enter.push(enterNodes);
1550
+ update.push(updateNodes);
1551
+ exit.push(exitNodes);
1552
+ }
1553
+
1554
+ var i = -1,
1555
+ n = this.length,
1556
+ group;
1557
+ if (typeof data === "function") {
1558
+ while (++i < n) {
1559
+ bind(group = this[i], data.call(group, group.parentNode.__data__, i));
1560
+ }
1561
+ } else {
1562
+ while (++i < n) {
1563
+ bind(group = this[i], data);
1564
+ }
1565
+ }
1566
+
1567
+ var selection = d3_selection(update);
1568
+ selection.enter = function() { return d3_selection_enter(enter); };
1569
+ selection.exit = function() { return d3_selection(exit); };
1570
+ return selection;
1571
+ };
1572
+
1573
+ function d3_selection_dataNode(data) {
1574
+ return {__data__: data};
1575
+ }
1576
+ function d3_selection_enter(selection) {
1577
+ d3_arraySubclass(selection, d3_selection_enterPrototype);
1578
+ return selection;
1579
+ }
1580
+
1581
+ var d3_selection_enterPrototype = [];
1582
+
1583
+ d3_selection_enterPrototype.append = d3_selectionPrototype.append;
1584
+ d3_selection_enterPrototype.insert = d3_selectionPrototype.insert;
1585
+ d3_selection_enterPrototype.empty = d3_selectionPrototype.empty;
1586
+ d3_selection_enterPrototype.select = function(selector) {
1587
+ var subgroups = [],
1588
+ subgroup,
1589
+ subnode,
1590
+ upgroup,
1591
+ group,
1592
+ node;
1593
+
1594
+ for (var j = -1, m = this.length; ++j < m;) {
1595
+ upgroup = (group = this[j]).update;
1596
+ subgroups.push(subgroup = []);
1597
+ subgroup.parentNode = group.parentNode;
1598
+ for (var i = -1, n = group.length; ++i < n;) {
1599
+ if (node = group[i]) {
1600
+ subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i));
1601
+ subnode.__data__ = node.__data__;
1602
+ } else {
1603
+ subgroup.push(null);
1604
+ }
1605
+ }
1606
+ }
1607
+
1608
+ return d3_selection(subgroups);
1609
+ };
1610
+ // TODO preserve null elements to maintain index?
1611
+ d3_selectionPrototype.filter = function(filter) {
1612
+ var subgroups = [],
1613
+ subgroup,
1614
+ group,
1615
+ node;
1616
+
1617
+ for (var j = 0, m = this.length; j < m; j++) {
1618
+ subgroups.push(subgroup = []);
1619
+ subgroup.parentNode = (group = this[j]).parentNode;
1620
+ for (var i = 0, n = group.length; i < n; i++) {
1621
+ if ((node = group[i]) && filter.call(node, node.__data__, i)) {
1622
+ subgroup.push(node);
1623
+ }
1624
+ }
1625
+ }
1626
+
1627
+ return d3_selection(subgroups);
1628
+ };
1629
+ d3_selectionPrototype.map = function(map) {
1630
+ return this.each(function() {
1631
+ this.__data__ = map.apply(this, arguments);
1632
+ });
1633
+ };
1634
+ d3_selectionPrototype.sort = function(comparator) {
1635
+ comparator = d3_selection_sortComparator.apply(this, arguments);
1636
+ for (var j = 0, m = this.length; j < m; j++) {
1637
+ for (var group = this[j].sort(comparator), i = 1, n = group.length, prev = group[0]; i < n; i++) {
1638
+ var node = group[i];
1639
+ if (node) {
1640
+ if (prev) prev.parentNode.insertBefore(node, prev.nextSibling);
1641
+ prev = node;
1642
+ }
1643
+ }
1644
+ }
1645
+ return this;
1646
+ };
1647
+
1648
+ function d3_selection_sortComparator(comparator) {
1649
+ if (!arguments.length) comparator = d3.ascending;
1650
+ return function(a, b) {
1651
+ return comparator(a && a.__data__, b && b.__data__);
1652
+ };
1653
+ }
1654
+ // type can be namespaced, e.g., "click.foo"
1655
+ // listener can be null for removal
1656
+ d3_selectionPrototype.on = function(type, listener, capture) {
1657
+ if (arguments.length < 3) capture = false;
1658
+
1659
+ // parse the type specifier
1660
+ var name = "__on" + type, i = type.indexOf(".");
1661
+ if (i > 0) type = type.substring(0, i);
1662
+
1663
+ // if called with only one argument, return the current listener
1664
+ if (arguments.length < 2) return (i = this.node()[name]) && i._;
1665
+
1666
+ // remove the old event listener, and add the new event listener
1667
+ return this.each(function(d, i) {
1668
+ var node = this;
1669
+
1670
+ if (node[name]) node.removeEventListener(type, node[name], capture);
1671
+ if (listener) node.addEventListener(type, node[name] = l, capture);
1672
+
1673
+ // wrapped event listener that preserves i
1674
+ function l(e) {
1675
+ var o = d3.event; // Events can be reentrant (e.g., focus).
1676
+ d3.event = e;
1677
+ try {
1678
+ listener.call(node, node.__data__, i);
1679
+ } finally {
1680
+ d3.event = o;
1681
+ }
1682
+ }
1683
+
1684
+ // stash the unwrapped listener for retrieval
1685
+ l._ = listener;
1686
+ });
1687
+ };
1688
+ d3_selectionPrototype.each = function(callback) {
1689
+ for (var j = -1, m = this.length; ++j < m;) {
1690
+ for (var group = this[j], i = -1, n = group.length; ++i < n;) {
1691
+ var node = group[i];
1692
+ if (node) callback.call(node, node.__data__, i, j);
1693
+ }
1694
+ }
1695
+ return this;
1696
+ };
1697
+ //
1698
+ // Note: assigning to the arguments array simultaneously changes the value of
1699
+ // the corresponding argument!
1700
+ //
1701
+ // TODO The `this` argument probably shouldn't be the first argument to the
1702
+ // callback, anyway, since it's redundant. However, that will require a major
1703
+ // version bump due to backwards compatibility, so I'm not changing it right
1704
+ // away.
1705
+ //
1706
+ d3_selectionPrototype.call = function(callback) {
1707
+ callback.apply(this, (arguments[0] = this, arguments));
1708
+ return this;
1709
+ };
1710
+ d3_selectionPrototype.empty = function() {
1711
+ return !this.node();
1712
+ };
1713
+ d3_selectionPrototype.node = function(callback) {
1714
+ for (var j = 0, m = this.length; j < m; j++) {
1715
+ for (var group = this[j], i = 0, n = group.length; i < n; i++) {
1716
+ var node = group[i];
1717
+ if (node) return node;
1718
+ }
1719
+ }
1720
+ return null;
1721
+ };
1722
+ d3_selectionPrototype.transition = function() {
1723
+ var subgroups = [],
1724
+ subgroup,
1725
+ node;
1726
+
1727
+ for (var j = -1, m = this.length; ++j < m;) {
1728
+ subgroups.push(subgroup = []);
1729
+ for (var group = this[j], i = -1, n = group.length; ++i < n;) {
1730
+ subgroup.push((node = group[i]) ? {node: node, delay: 0, duration: 250} : null);
1731
+ }
1732
+ }
1733
+
1734
+ return d3_transition(subgroups, d3_transitionInheritId || ++d3_transitionId);
1735
+ };
1736
+ var d3_selectionRoot = d3_selection([[document]]);
1737
+
1738
+ d3_selectionRoot[0].parentNode = document.documentElement;
1739
+
1740
+ // TODO fast singleton implementation!
1741
+ d3.select = function(selector) {
1742
+ return typeof selector === "string"
1743
+ ? d3_selectionRoot.select(selector)
1744
+ : d3_selection([[selector]]); // assume node
1745
+ };
1746
+
1747
+ d3.selectAll = function(selector) {
1748
+ return typeof selector === "string"
1749
+ ? d3_selectionRoot.selectAll(selector)
1750
+ : d3_selection([selector]); // assume node[]
1751
+ };
1752
+ function d3_transition(groups, id) {
1753
+ d3_arraySubclass(groups, d3_transitionPrototype);
1754
+
1755
+ var tweens = {},
1756
+ event = d3.dispatch("start", "end"),
1757
+ ease = d3_transitionEase,
1758
+ then = Date.now();
1759
+
1760
+ groups.id = id;
1761
+
1762
+ groups.tween = function(name, tween) {
1763
+ if (arguments.length < 2) return tweens[name];
1764
+ if (tween == null) delete tweens[name];
1765
+ else tweens[name] = tween;
1766
+ return groups;
1767
+ };
1768
+
1769
+ groups.ease = function(value) {
1770
+ if (!arguments.length) return ease;
1771
+ ease = typeof value === "function" ? value : d3.ease.apply(d3, arguments);
1772
+ return groups;
1773
+ };
1774
+
1775
+ groups.each = function(type, listener) {
1776
+ if (arguments.length < 2) return d3_transition_each.call(groups, type);
1777
+ event[type].add(listener);
1778
+ return groups;
1779
+ };
1780
+
1781
+ d3.timer(function(elapsed) {
1782
+ groups.each(function(d, i, j) {
1783
+ var tweened = [],
1784
+ node = this,
1785
+ delay = groups[j][i].delay,
1786
+ duration = groups[j][i].duration,
1787
+ lock = node.__transition__ || (node.__transition__ = {active: 0, count: 0});
1788
+
1789
+ ++lock.count;
1790
+
1791
+ delay <= elapsed ? start(elapsed) : d3.timer(start, delay, then);
1792
+
1793
+ function start(elapsed) {
1794
+ if (lock.active > id) return stop();
1795
+ lock.active = id;
1796
+
1797
+ for (var tween in tweens) {
1798
+ if (tween = tweens[tween].call(node, d, i)) {
1799
+ tweened.push(tween);
1800
+ }
1801
+ }
1802
+
1803
+ event.start.dispatch.call(node, d, i);
1804
+ if (!tick(elapsed)) d3.timer(tick, 0, then);
1805
+ return 1;
1806
+ }
1807
+
1808
+ function tick(elapsed) {
1809
+ if (lock.active !== id) return stop();
1810
+
1811
+ var t = (elapsed - delay) / duration,
1812
+ e = ease(t),
1813
+ n = tweened.length;
1814
+
1815
+ while (n > 0) {
1816
+ tweened[--n].call(node, e);
1817
+ }
1818
+
1819
+ if (t >= 1) {
1820
+ stop();
1821
+ d3_transitionInheritId = id;
1822
+ event.end.dispatch.call(node, d, i);
1823
+ d3_transitionInheritId = 0;
1824
+ return 1;
1825
+ }
1826
+ }
1827
+
1828
+ function stop() {
1829
+ if (!--lock.count) delete node.__transition__;
1830
+ return 1;
1831
+ }
1832
+ });
1833
+ return 1;
1834
+ }, 0, then);
1835
+
1836
+ return groups;
1837
+ }
1838
+
1839
+ function d3_transitionTween(b) {
1840
+ return typeof b === "function"
1841
+ ? function(d, i, a) { var v = b.call(this, d, i) + ""; return a != v && d3.interpolate(a, v); }
1842
+ : (b = b + "", function(d, i, a) { return a != b && d3.interpolate(a, b); });
1843
+ }
1844
+
1845
+ var d3_transitionPrototype = [],
1846
+ d3_transitionId = 0,
1847
+ d3_transitionInheritId = 0,
1848
+ d3_transitionEase = d3.ease("cubic-in-out");
1849
+
1850
+ d3_transitionPrototype.call = d3_selectionPrototype.call;
1851
+
1852
+ d3.transition = function() {
1853
+ return d3_selectionRoot.transition();
1854
+ };
1855
+
1856
+ d3.transition.prototype = d3_transitionPrototype;
1857
+ d3_transitionPrototype.select = function(selector) {
1858
+ var subgroups = [],
1859
+ subgroup,
1860
+ subnode,
1861
+ node;
1862
+
1863
+ if (typeof selector !== "function") selector = d3_selection_selector(selector);
1864
+
1865
+ for (var j = -1, m = this.length; ++j < m;) {
1866
+ subgroups.push(subgroup = []);
1867
+ for (var group = this[j], i = -1, n = group.length; ++i < n;) {
1868
+ if ((node = group[i]) && (subnode = selector.call(node.node, node.node.__data__, i))) {
1869
+ if ("__data__" in node.node) subnode.__data__ = node.node.__data__;
1870
+ subgroup.push({node: subnode, delay: node.delay, duration: node.duration});
1871
+ } else {
1872
+ subgroup.push(null);
1873
+ }
1874
+ }
1875
+ }
1876
+
1877
+ return d3_transition(subgroups, this.id).ease(this.ease());
1878
+ };
1879
+ d3_transitionPrototype.selectAll = function(selector) {
1880
+ var subgroups = [],
1881
+ subgroup,
1882
+ node;
1883
+
1884
+ if (typeof selector !== "function") selector = d3_selection_selectorAll(selector);
1885
+
1886
+ for (var j = -1, m = this.length; ++j < m;) {
1887
+ for (var group = this[j], i = -1, n = group.length; ++i < n;) {
1888
+ if (node = group[i]) {
1889
+ subgroups.push(subgroup = selector.call(node.node, node.node.__data__, i));
1890
+ for (var k = -1, o = subgroup.length; ++k < o;) {
1891
+ subgroup[k] = {node: subgroup[k], delay: node.delay, duration: node.duration};
1892
+ }
1893
+ }
1894
+ }
1895
+ }
1896
+
1897
+ return d3_transition(subgroups, this.id).ease(this.ease());
1898
+ };
1899
+ d3_transitionPrototype.attr = function(name, value) {
1900
+ return this.attrTween(name, d3_transitionTween(value));
1901
+ };
1902
+
1903
+ d3_transitionPrototype.attrTween = function(name, tween) {
1904
+ name = d3.ns.qualify(name);
1905
+
1906
+ function attrTween(d, i) {
1907
+ var f = tween.call(this, d, i, this.getAttribute(name));
1908
+ return f && function(t) {
1909
+ this.setAttribute(name, f(t));
1910
+ };
1911
+ }
1912
+
1913
+ function attrTweenNS(d, i) {
1914
+ var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local));
1915
+ return f && function(t) {
1916
+ this.setAttributeNS(name.space, name.local, f(t));
1917
+ };
1918
+ }
1919
+
1920
+ return this.tween("attr." + name, name.local ? attrTweenNS : attrTween);
1921
+ };
1922
+ d3_transitionPrototype.style = function(name, value, priority) {
1923
+ if (arguments.length < 3) priority = "";
1924
+ return this.styleTween(name, d3_transitionTween(value), priority);
1925
+ };
1926
+
1927
+ d3_transitionPrototype.styleTween = function(name, tween, priority) {
1928
+ if (arguments.length < 3) priority = "";
1929
+ return this.tween("style." + name, function(d, i) {
1930
+ var f = tween.call(this, d, i, window.getComputedStyle(this, null).getPropertyValue(name));
1931
+ return f && function(t) {
1932
+ this.style.setProperty(name, f(t), priority);
1933
+ };
1934
+ });
1935
+ };
1936
+ d3_transitionPrototype.text = function(value) {
1937
+ return this.tween("text", function(d, i) {
1938
+ this.textContent = typeof value === "function"
1939
+ ? value.call(this, d, i)
1940
+ : value;
1941
+ });
1942
+ };
1943
+ d3_transitionPrototype.remove = function() {
1944
+ return this.each("end", function() {
1945
+ var p;
1946
+ if (!this.__transition__ && (p = this.parentNode)) p.removeChild(this);
1947
+ });
1948
+ };
1949
+ d3_transitionPrototype.delay = function(value) {
1950
+ var groups = this;
1951
+ return groups.each(typeof value === "function"
1952
+ ? function(d, i, j) { groups[j][i].delay = +value.apply(this, arguments); }
1953
+ : (value = +value, function(d, i, j) { groups[j][i].delay = value; }));
1954
+ };
1955
+ d3_transitionPrototype.duration = function(value) {
1956
+ var groups = this;
1957
+ return groups.each(typeof value === "function"
1958
+ ? function(d, i, j) { groups[j][i].duration = +value.apply(this, arguments); }
1959
+ : (value = +value, function(d, i, j) { groups[j][i].duration = value; }));
1960
+ };
1961
+ function d3_transition_each(callback) {
1962
+ for (var j = 0, m = this.length; j < m; j++) {
1963
+ for (var group = this[j], i = 0, n = group.length; i < n; i++) {
1964
+ var node = group[i];
1965
+ if (node) callback.call(node = node.node, node.__data__, i, j);
1966
+ }
1967
+ }
1968
+ return this;
1969
+ }
1970
+ d3_transitionPrototype.transition = function() {
1971
+ return this.select(d3_this);
1972
+ };
1973
+ var d3_timer_queue = null,
1974
+ d3_timer_interval, // is an interval (or frame) active?
1975
+ d3_timer_timeout; // is a timeout active?
1976
+
1977
+ // The timer will continue to fire until callback returns true.
1978
+ d3.timer = function(callback, delay, then) {
1979
+ var found = false,
1980
+ t0,
1981
+ t1 = d3_timer_queue;
1982
+
1983
+ if (arguments.length < 3) {
1984
+ if (arguments.length < 2) delay = 0;
1985
+ else if (!isFinite(delay)) return;
1986
+ then = Date.now();
1987
+ }
1988
+
1989
+ // See if the callback's already in the queue.
1990
+ while (t1) {
1991
+ if (t1.callback === callback) {
1992
+ t1.then = then;
1993
+ t1.delay = delay;
1994
+ found = true;
1995
+ break;
1996
+ }
1997
+ t0 = t1;
1998
+ t1 = t1.next;
1999
+ }
2000
+
2001
+ // Otherwise, add the callback to the queue.
2002
+ if (!found) d3_timer_queue = {
2003
+ callback: callback,
2004
+ then: then,
2005
+ delay: delay,
2006
+ next: d3_timer_queue
2007
+ };
2008
+
2009
+ // Start animatin'!
2010
+ if (!d3_timer_interval) {
2011
+ d3_timer_timeout = clearTimeout(d3_timer_timeout);
2012
+ d3_timer_interval = 1;
2013
+ d3_timer_frame(d3_timer_step);
2014
+ }
2015
+ }
2016
+
2017
+ function d3_timer_step() {
2018
+ var elapsed,
2019
+ now = Date.now(),
2020
+ t1 = d3_timer_queue;
2021
+
2022
+ while (t1) {
2023
+ elapsed = now - t1.then;
2024
+ if (elapsed >= t1.delay) t1.flush = t1.callback(elapsed);
2025
+ t1 = t1.next;
2026
+ }
2027
+
2028
+ var delay = d3_timer_flush() - now;
2029
+ if (delay > 24) {
2030
+ if (isFinite(delay)) {
2031
+ clearTimeout(d3_timer_timeout);
2032
+ d3_timer_timeout = setTimeout(d3_timer_step, delay);
2033
+ }
2034
+ d3_timer_interval = 0;
2035
+ } else {
2036
+ d3_timer_interval = 1;
2037
+ d3_timer_frame(d3_timer_step);
2038
+ }
2039
+ }
2040
+
2041
+ d3.timer.flush = function() {
2042
+ var elapsed,
2043
+ now = Date.now(),
2044
+ t1 = d3_timer_queue;
2045
+
2046
+ while (t1) {
2047
+ elapsed = now - t1.then;
2048
+ if (!t1.delay) t1.flush = t1.callback(elapsed);
2049
+ t1 = t1.next;
2050
+ }
2051
+
2052
+ d3_timer_flush();
2053
+ };
2054
+
2055
+ // Flush after callbacks, to avoid concurrent queue modification.
2056
+ function d3_timer_flush() {
2057
+ var t0 = null,
2058
+ t1 = d3_timer_queue,
2059
+ then = Infinity;
2060
+ while (t1) {
2061
+ if (t1.flush) {
2062
+ t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next;
2063
+ } else {
2064
+ then = Math.min(then, t1.then + t1.delay);
2065
+ t1 = (t0 = t1).next;
2066
+ }
2067
+ }
2068
+ return then;
2069
+ }
2070
+
2071
+ var d3_timer_frame = window.requestAnimationFrame
2072
+ || window.webkitRequestAnimationFrame
2073
+ || window.mozRequestAnimationFrame
2074
+ || window.oRequestAnimationFrame
2075
+ || window.msRequestAnimationFrame
2076
+ || function(callback) { setTimeout(callback, 17); };
2077
+ function d3_noop() {}
2078
+ d3.scale = {};
2079
+
2080
+ function d3_scaleExtent(domain) {
2081
+ var start = domain[0], stop = domain[domain.length - 1];
2082
+ return start < stop ? [start, stop] : [stop, start];
2083
+ }
2084
+ function d3_scale_nice(domain, nice) {
2085
+ var i0 = 0,
2086
+ i1 = domain.length - 1,
2087
+ x0 = domain[i0],
2088
+ x1 = domain[i1],
2089
+ dx;
2090
+
2091
+ if (x1 < x0) {
2092
+ dx = i0; i0 = i1; i1 = dx;
2093
+ dx = x0; x0 = x1; x1 = dx;
2094
+ }
2095
+
2096
+ nice = nice(x1 - x0);
2097
+ domain[i0] = nice.floor(x0);
2098
+ domain[i1] = nice.ceil(x1);
2099
+ return domain;
2100
+ }
2101
+
2102
+ function d3_scale_niceDefault() {
2103
+ return Math;
2104
+ }
2105
+ d3.scale.linear = function() {
2106
+ return d3_scale_linear([0, 1], [0, 1], d3.interpolate, false);
2107
+ };
2108
+
2109
+ function d3_scale_linear(domain, range, interpolate, clamp) {
2110
+ var output,
2111
+ input;
2112
+
2113
+ function rescale() {
2114
+ var linear = domain.length == 2 ? d3_scale_bilinear : d3_scale_polylinear,
2115
+ uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
2116
+ output = linear(domain, range, uninterpolate, interpolate);
2117
+ input = linear(range, domain, uninterpolate, d3.interpolate);
2118
+ return scale;
2119
+ }
2120
+
2121
+ function scale(x) {
2122
+ return output(x);
2123
+ }
2124
+
2125
+ // Note: requires range is coercible to number!
2126
+ scale.invert = function(y) {
2127
+ return input(y);
2128
+ };
2129
+
2130
+ scale.domain = function(x) {
2131
+ if (!arguments.length) return domain;
2132
+ domain = x.map(Number);
2133
+ return rescale();
2134
+ };
2135
+
2136
+ scale.range = function(x) {
2137
+ if (!arguments.length) return range;
2138
+ range = x;
2139
+ return rescale();
2140
+ };
2141
+
2142
+ scale.rangeRound = function(x) {
2143
+ return scale.range(x).interpolate(d3.interpolateRound);
2144
+ };
2145
+
2146
+ scale.clamp = function(x) {
2147
+ if (!arguments.length) return clamp;
2148
+ clamp = x;
2149
+ return rescale();
2150
+ };
2151
+
2152
+ scale.interpolate = function(x) {
2153
+ if (!arguments.length) return interpolate;
2154
+ interpolate = x;
2155
+ return rescale();
2156
+ };
2157
+
2158
+ scale.ticks = function(m) {
2159
+ return d3_scale_linearTicks(domain, m);
2160
+ };
2161
+
2162
+ scale.tickFormat = function(m) {
2163
+ return d3_scale_linearTickFormat(domain, m);
2164
+ };
2165
+
2166
+ scale.nice = function() {
2167
+ d3_scale_nice(domain, d3_scale_linearNice);
2168
+ return rescale();
2169
+ };
2170
+
2171
+ scale.copy = function() {
2172
+ return d3_scale_linear(domain, range, interpolate, clamp);
2173
+ };
2174
+
2175
+ return rescale();
2176
+ };
2177
+
2178
+ function d3_scale_linearRebind(scale, linear) {
2179
+ scale.range = d3.rebind(scale, linear.range);
2180
+ scale.rangeRound = d3.rebind(scale, linear.rangeRound);
2181
+ scale.interpolate = d3.rebind(scale, linear.interpolate);
2182
+ scale.clamp = d3.rebind(scale, linear.clamp);
2183
+ return scale;
2184
+ }
2185
+
2186
+ function d3_scale_linearNice(dx) {
2187
+ dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1);
2188
+ return {
2189
+ floor: function(x) { return Math.floor(x / dx) * dx; },
2190
+ ceil: function(x) { return Math.ceil(x / dx) * dx; }
2191
+ };
2192
+ }
2193
+
2194
+ // TODO Dates? Ugh.
2195
+ function d3_scale_linearTickRange(domain, m) {
2196
+ var extent = d3_scaleExtent(domain),
2197
+ span = extent[1] - extent[0],
2198
+ step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)),
2199
+ err = m / span * step;
2200
+
2201
+ // Filter ticks to get closer to the desired count.
2202
+ if (err <= .15) step *= 10;
2203
+ else if (err <= .35) step *= 5;
2204
+ else if (err <= .75) step *= 2;
2205
+
2206
+ // Round start and stop values to step interval.
2207
+ extent[0] = Math.ceil(extent[0] / step) * step;
2208
+ extent[1] = Math.floor(extent[1] / step) * step + step * .5; // inclusive
2209
+ extent[2] = step;
2210
+ return extent;
2211
+ }
2212
+
2213
+ function d3_scale_linearTicks(domain, m) {
2214
+ return d3.range.apply(d3, d3_scale_linearTickRange(domain, m));
2215
+ }
2216
+
2217
+ function d3_scale_linearTickFormat(domain, m) {
2218
+ return d3.format(",." + Math.max(0, -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01)) + "f");
2219
+ }
2220
+ function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
2221
+ var u = uninterpolate(domain[0], domain[1]),
2222
+ i = interpolate(range[0], range[1]);
2223
+ return function(x) {
2224
+ return i(u(x));
2225
+ };
2226
+ }
2227
+ function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
2228
+ var u = [],
2229
+ i = [],
2230
+ j = 0,
2231
+ n = domain.length;
2232
+
2233
+ while (++j < n) {
2234
+ u.push(uninterpolate(domain[j - 1], domain[j]));
2235
+ i.push(interpolate(range[j - 1], range[j]));
2236
+ }
2237
+
2238
+ return function(x) {
2239
+ var j = d3.bisect(domain, x, 1, domain.length - 1) - 1;
2240
+ return i[j](u[j](x));
2241
+ };
2242
+ }
2243
+ d3.scale.log = function() {
2244
+ return d3_scale_log(d3.scale.linear(), d3_scale_logp);
2245
+ };
2246
+
2247
+ function d3_scale_log(linear, log) {
2248
+ var pow = log.pow;
2249
+
2250
+ function scale(x) {
2251
+ return linear(log(x));
2252
+ }
2253
+
2254
+ scale.invert = function(x) {
2255
+ return pow(linear.invert(x));
2256
+ };
2257
+
2258
+ scale.domain = function(x) {
2259
+ if (!arguments.length) return linear.domain().map(pow);
2260
+ log = x[0] < 0 ? d3_scale_logn : d3_scale_logp;
2261
+ pow = log.pow;
2262
+ linear.domain(x.map(log));
2263
+ return scale;
2264
+ };
2265
+
2266
+ scale.nice = function() {
2267
+ linear.domain(d3_scale_nice(linear.domain(), d3_scale_niceDefault));
2268
+ return scale;
2269
+ };
2270
+
2271
+ scale.ticks = function() {
2272
+ var extent = d3_scaleExtent(linear.domain()),
2273
+ ticks = [];
2274
+ if (extent.every(isFinite)) {
2275
+ var i = Math.floor(extent[0]),
2276
+ j = Math.ceil(extent[1]),
2277
+ u = pow(extent[0]),
2278
+ v = pow(extent[1]);
2279
+ if (log === d3_scale_logn) {
2280
+ ticks.push(pow(i));
2281
+ for (; i++ < j;) for (var k = 9; k > 0; k--) ticks.push(pow(i) * k);
2282
+ } else {
2283
+ for (; i < j; i++) for (var k = 1; k < 10; k++) ticks.push(pow(i) * k);
2284
+ ticks.push(pow(i));
2285
+ }
2286
+ for (i = 0; ticks[i] < u; i++) {} // strip small values
2287
+ for (j = ticks.length; ticks[j - 1] > v; j--) {} // strip big values
2288
+ ticks = ticks.slice(i, j);
2289
+ }
2290
+ return ticks;
2291
+ };
2292
+
2293
+ scale.tickFormat = function() {
2294
+ return d3_scale_logTickFormat;
2295
+ };
2296
+
2297
+ scale.copy = function() {
2298
+ return d3_scale_log(linear.copy(), log);
2299
+ };
2300
+
2301
+ return d3_scale_linearRebind(scale, linear);
2302
+ };
2303
+
2304
+ function d3_scale_logp(x) {
2305
+ return Math.log(x) / Math.LN10;
2306
+ }
2307
+
2308
+ function d3_scale_logn(x) {
2309
+ return -Math.log(-x) / Math.LN10;
2310
+ }
2311
+
2312
+ d3_scale_logp.pow = function(x) {
2313
+ return Math.pow(10, x);
2314
+ };
2315
+
2316
+ d3_scale_logn.pow = function(x) {
2317
+ return -Math.pow(10, -x);
2318
+ };
2319
+
2320
+ function d3_scale_logTickFormat(d) {
2321
+ return d.toPrecision(1);
2322
+ }
2323
+ d3.scale.pow = function() {
2324
+ return d3_scale_pow(d3.scale.linear(), 1);
2325
+ };
2326
+
2327
+ function d3_scale_pow(linear, exponent) {
2328
+ var powp = d3_scale_powPow(exponent),
2329
+ powb = d3_scale_powPow(1 / exponent);
2330
+
2331
+ function scale(x) {
2332
+ return linear(powp(x));
2333
+ }
2334
+
2335
+ scale.invert = function(x) {
2336
+ return powb(linear.invert(x));
2337
+ };
2338
+
2339
+ scale.domain = function(x) {
2340
+ if (!arguments.length) return linear.domain().map(powb);
2341
+ linear.domain(x.map(powp));
2342
+ return scale;
2343
+ };
2344
+
2345
+ scale.ticks = function(m) {
2346
+ return d3_scale_linearTicks(scale.domain(), m);
2347
+ };
2348
+
2349
+ scale.tickFormat = function(m) {
2350
+ return d3_scale_linearTickFormat(scale.domain(), m);
2351
+ };
2352
+
2353
+ scale.nice = function() {
2354
+ return scale.domain(d3_scale_nice(scale.domain(), d3_scale_linearNice));
2355
+ };
2356
+
2357
+ scale.exponent = function(x) {
2358
+ if (!arguments.length) return exponent;
2359
+ var domain = scale.domain();
2360
+ powp = d3_scale_powPow(exponent = x);
2361
+ powb = d3_scale_powPow(1 / exponent);
2362
+ return scale.domain(domain);
2363
+ };
2364
+
2365
+ scale.copy = function() {
2366
+ return d3_scale_pow(linear.copy(), exponent);
2367
+ };
2368
+
2369
+ return d3_scale_linearRebind(scale, linear);
2370
+ };
2371
+
2372
+ function d3_scale_powPow(e) {
2373
+ return function(x) {
2374
+ return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e);
2375
+ };
2376
+ }
2377
+ d3.scale.sqrt = function() {
2378
+ return d3.scale.pow().exponent(.5);
2379
+ };
2380
+ d3.scale.ordinal = function() {
2381
+ return d3_scale_ordinal([], {t: "range", x: []});
2382
+ };
2383
+
2384
+ function d3_scale_ordinal(domain, ranger) {
2385
+ var index,
2386
+ range,
2387
+ rangeBand;
2388
+
2389
+ function scale(x) {
2390
+ return range[((index[x] || (index[x] = domain.push(x))) - 1) % range.length];
2391
+ }
2392
+
2393
+ scale.domain = function(x) {
2394
+ if (!arguments.length) return domain;
2395
+ domain = [];
2396
+ index = {};
2397
+ var i = -1, n = x.length, xi;
2398
+ while (++i < n) if (!index[xi = x[i]]) index[xi] = domain.push(xi);
2399
+ return scale[ranger.t](ranger.x, ranger.p);
2400
+ };
2401
+
2402
+ scale.range = function(x) {
2403
+ if (!arguments.length) return range;
2404
+ range = x;
2405
+ rangeBand = 0;
2406
+ ranger = {t: "range", x: x};
2407
+ return scale;
2408
+ };
2409
+
2410
+ scale.rangePoints = function(x, padding) {
2411
+ if (arguments.length < 2) padding = 0;
2412
+ var start = x[0],
2413
+ stop = x[1],
2414
+ step = (stop - start) / (domain.length - 1 + padding);
2415
+ range = domain.length < 2 ? [(start + stop) / 2] : d3.range(start + step * padding / 2, stop + step / 2, step);
2416
+ rangeBand = 0;
2417
+ ranger = {t: "rangePoints", x: x, p: padding};
2418
+ return scale;
2419
+ };
2420
+
2421
+ scale.rangeBands = function(x, padding) {
2422
+ if (arguments.length < 2) padding = 0;
2423
+ var start = x[0],
2424
+ stop = x[1],
2425
+ step = (stop - start) / (domain.length + padding);
2426
+ range = d3.range(start + step * padding, stop, step);
2427
+ rangeBand = step * (1 - padding);
2428
+ ranger = {t: "rangeBands", x: x, p: padding};
2429
+ return scale;
2430
+ };
2431
+
2432
+ scale.rangeRoundBands = function(x, padding) {
2433
+ if (arguments.length < 2) padding = 0;
2434
+ var start = x[0],
2435
+ stop = x[1],
2436
+ step = Math.floor((stop - start) / (domain.length + padding)),
2437
+ err = stop - start - (domain.length - padding) * step;
2438
+ range = d3.range(start + Math.round(err / 2), stop, step);
2439
+ rangeBand = Math.round(step * (1 - padding));
2440
+ ranger = {t: "rangeRoundBands", x: x, p: padding};
2441
+ return scale;
2442
+ };
2443
+
2444
+ scale.rangeBand = function() {
2445
+ return rangeBand;
2446
+ };
2447
+
2448
+ scale.copy = function() {
2449
+ return d3_scale_ordinal(domain, ranger);
2450
+ };
2451
+
2452
+ return scale.domain(domain);
2453
+ };
2454
+ /*
2455
+ * This product includes color specifications and designs developed by Cynthia
2456
+ * Brewer (http://colorbrewer.org/). See lib/colorbrewer for more information.
2457
+ */
2458
+
2459
+ d3.scale.category10 = function() {
2460
+ return d3.scale.ordinal().range(d3_category10);
2461
+ };
2462
+
2463
+ d3.scale.category20 = function() {
2464
+ return d3.scale.ordinal().range(d3_category20);
2465
+ };
2466
+
2467
+ d3.scale.category20b = function() {
2468
+ return d3.scale.ordinal().range(d3_category20b);
2469
+ };
2470
+
2471
+ d3.scale.category20c = function() {
2472
+ return d3.scale.ordinal().range(d3_category20c);
2473
+ };
2474
+
2475
+ var d3_category10 = [
2476
+ "#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd",
2477
+ "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf"
2478
+ ];
2479
+
2480
+ var d3_category20 = [
2481
+ "#1f77b4", "#aec7e8",
2482
+ "#ff7f0e", "#ffbb78",
2483
+ "#2ca02c", "#98df8a",
2484
+ "#d62728", "#ff9896",
2485
+ "#9467bd", "#c5b0d5",
2486
+ "#8c564b", "#c49c94",
2487
+ "#e377c2", "#f7b6d2",
2488
+ "#7f7f7f", "#c7c7c7",
2489
+ "#bcbd22", "#dbdb8d",
2490
+ "#17becf", "#9edae5"
2491
+ ];
2492
+
2493
+ var d3_category20b = [
2494
+ "#393b79", "#5254a3", "#6b6ecf", "#9c9ede",
2495
+ "#637939", "#8ca252", "#b5cf6b", "#cedb9c",
2496
+ "#8c6d31", "#bd9e39", "#e7ba52", "#e7cb94",
2497
+ "#843c39", "#ad494a", "#d6616b", "#e7969c",
2498
+ "#7b4173", "#a55194", "#ce6dbd", "#de9ed6"
2499
+ ];
2500
+
2501
+ var d3_category20c = [
2502
+ "#3182bd", "#6baed6", "#9ecae1", "#c6dbef",
2503
+ "#e6550d", "#fd8d3c", "#fdae6b", "#fdd0a2",
2504
+ "#31a354", "#74c476", "#a1d99b", "#c7e9c0",
2505
+ "#756bb1", "#9e9ac8", "#bcbddc", "#dadaeb",
2506
+ "#636363", "#969696", "#bdbdbd", "#d9d9d9"
2507
+ ];
2508
+ d3.scale.quantile = function() {
2509
+ return d3_scale_quantile([], []);
2510
+ };
2511
+
2512
+ function d3_scale_quantile(domain, range) {
2513
+ var thresholds;
2514
+
2515
+ function rescale() {
2516
+ var k = 0,
2517
+ n = domain.length,
2518
+ q = range.length;
2519
+ thresholds = [];
2520
+ while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q);
2521
+ return scale;
2522
+ }
2523
+
2524
+ function scale(x) {
2525
+ if (isNaN(x = +x)) return NaN;
2526
+ return range[d3.bisect(thresholds, x)];
2527
+ }
2528
+
2529
+ scale.domain = function(x) {
2530
+ if (!arguments.length) return domain;
2531
+ domain = x.filter(function(d) { return !isNaN(d); }).sort(d3.ascending);
2532
+ return rescale();
2533
+ };
2534
+
2535
+ scale.range = function(x) {
2536
+ if (!arguments.length) return range;
2537
+ range = x;
2538
+ return rescale();
2539
+ };
2540
+
2541
+ scale.quantiles = function() {
2542
+ return thresholds;
2543
+ };
2544
+
2545
+ scale.copy = function() {
2546
+ return d3_scale_quantile(domain, range); // copy on write!
2547
+ };
2548
+
2549
+ return rescale();
2550
+ };
2551
+ d3.scale.quantize = function() {
2552
+ return d3_scale_quantize(0, 1, [0, 1]);
2553
+ };
2554
+
2555
+ function d3_scale_quantize(x0, x1, range) {
2556
+ var kx, i;
2557
+
2558
+ function scale(x) {
2559
+ return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))];
2560
+ }
2561
+
2562
+ function rescale() {
2563
+ kx = range.length / (x1 - x0);
2564
+ i = range.length - 1;
2565
+ return scale;
2566
+ }
2567
+
2568
+ scale.domain = function(x) {
2569
+ if (!arguments.length) return [x0, x1];
2570
+ x0 = +x[0];
2571
+ x1 = +x[x.length - 1];
2572
+ return rescale();
2573
+ };
2574
+
2575
+ scale.range = function(x) {
2576
+ if (!arguments.length) return range;
2577
+ range = x;
2578
+ return rescale();
2579
+ };
2580
+
2581
+ scale.copy = function() {
2582
+ return d3_scale_quantize(x0, x1, range); // copy on write
2583
+ };
2584
+
2585
+ return rescale();
2586
+ };
2587
+ d3.svg = {};
2588
+ d3.svg.arc = function() {
2589
+ var innerRadius = d3_svg_arcInnerRadius,
2590
+ outerRadius = d3_svg_arcOuterRadius,
2591
+ startAngle = d3_svg_arcStartAngle,
2592
+ endAngle = d3_svg_arcEndAngle;
2593
+
2594
+ function arc() {
2595
+ var r0 = innerRadius.apply(this, arguments),
2596
+ r1 = outerRadius.apply(this, arguments),
2597
+ a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset,
2598
+ a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset,
2599
+ da = (a1 < a0 && (da = a0, a0 = a1, a1 = da), a1 - a0),
2600
+ df = da < Math.PI ? "0" : "1",
2601
+ c0 = Math.cos(a0),
2602
+ s0 = Math.sin(a0),
2603
+ c1 = Math.cos(a1),
2604
+ s1 = Math.sin(a1);
2605
+ return da >= d3_svg_arcMax
2606
+ ? (r0
2607
+ ? "M0," + r1
2608
+ + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1)
2609
+ + "A" + r1 + "," + r1 + " 0 1,1 0," + r1
2610
+ + "M0," + r0
2611
+ + "A" + r0 + "," + r0 + " 0 1,0 0," + (-r0)
2612
+ + "A" + r0 + "," + r0 + " 0 1,0 0," + r0
2613
+ + "Z"
2614
+ : "M0," + r1
2615
+ + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1)
2616
+ + "A" + r1 + "," + r1 + " 0 1,1 0," + r1
2617
+ + "Z")
2618
+ : (r0
2619
+ ? "M" + r1 * c0 + "," + r1 * s0
2620
+ + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1
2621
+ + "L" + r0 * c1 + "," + r0 * s1
2622
+ + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0
2623
+ + "Z"
2624
+ : "M" + r1 * c0 + "," + r1 * s0
2625
+ + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1
2626
+ + "L0,0"
2627
+ + "Z");
2628
+ }
2629
+
2630
+ arc.innerRadius = function(v) {
2631
+ if (!arguments.length) return innerRadius;
2632
+ innerRadius = d3.functor(v);
2633
+ return arc;
2634
+ };
2635
+
2636
+ arc.outerRadius = function(v) {
2637
+ if (!arguments.length) return outerRadius;
2638
+ outerRadius = d3.functor(v);
2639
+ return arc;
2640
+ };
2641
+
2642
+ arc.startAngle = function(v) {
2643
+ if (!arguments.length) return startAngle;
2644
+ startAngle = d3.functor(v);
2645
+ return arc;
2646
+ };
2647
+
2648
+ arc.endAngle = function(v) {
2649
+ if (!arguments.length) return endAngle;
2650
+ endAngle = d3.functor(v);
2651
+ return arc;
2652
+ };
2653
+
2654
+ arc.centroid = function() {
2655
+ var r = (innerRadius.apply(this, arguments)
2656
+ + outerRadius.apply(this, arguments)) / 2,
2657
+ a = (startAngle.apply(this, arguments)
2658
+ + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset;
2659
+ return [Math.cos(a) * r, Math.sin(a) * r];
2660
+ };
2661
+
2662
+ return arc;
2663
+ };
2664
+
2665
+ var d3_svg_arcOffset = -Math.PI / 2,
2666
+ d3_svg_arcMax = 2 * Math.PI - 1e-6;
2667
+
2668
+ function d3_svg_arcInnerRadius(d) {
2669
+ return d.innerRadius;
2670
+ }
2671
+
2672
+ function d3_svg_arcOuterRadius(d) {
2673
+ return d.outerRadius;
2674
+ }
2675
+
2676
+ function d3_svg_arcStartAngle(d) {
2677
+ return d.startAngle;
2678
+ }
2679
+
2680
+ function d3_svg_arcEndAngle(d) {
2681
+ return d.endAngle;
2682
+ }
2683
+ function d3_svg_line(projection) {
2684
+ var x = d3_svg_lineX,
2685
+ y = d3_svg_lineY,
2686
+ interpolate = "linear",
2687
+ interpolator = d3_svg_lineInterpolators[interpolate],
2688
+ tension = .7;
2689
+
2690
+ function line(d) {
2691
+ return d.length < 1 ? null : "M" + interpolator(projection(d3_svg_linePoints(this, d, x, y)), tension);
2692
+ }
2693
+
2694
+ line.x = function(v) {
2695
+ if (!arguments.length) return x;
2696
+ x = v;
2697
+ return line;
2698
+ };
2699
+
2700
+ line.y = function(v) {
2701
+ if (!arguments.length) return y;
2702
+ y = v;
2703
+ return line;
2704
+ };
2705
+
2706
+ line.interpolate = function(v) {
2707
+ if (!arguments.length) return interpolate;
2708
+ interpolator = d3_svg_lineInterpolators[interpolate = v];
2709
+ return line;
2710
+ };
2711
+
2712
+ line.tension = function(v) {
2713
+ if (!arguments.length) return tension;
2714
+ tension = v;
2715
+ return line;
2716
+ };
2717
+
2718
+ return line;
2719
+ }
2720
+
2721
+ d3.svg.line = function() {
2722
+ return d3_svg_line(Object);
2723
+ };
2724
+
2725
+ // Converts the specified array of data into an array of points
2726
+ // (x-y tuples), by evaluating the specified `x` and `y` functions on each
2727
+ // data point. The `this` context of the evaluated functions is the specified
2728
+ // "self" object; each function is passed the current datum and index.
2729
+ function d3_svg_linePoints(self, d, x, y) {
2730
+ var points = [],
2731
+ i = -1,
2732
+ n = d.length,
2733
+ fx = typeof x === "function",
2734
+ fy = typeof y === "function",
2735
+ value;
2736
+ if (fx && fy) {
2737
+ while (++i < n) points.push([
2738
+ x.call(self, value = d[i], i),
2739
+ y.call(self, value, i)
2740
+ ]);
2741
+ } else if (fx) {
2742
+ while (++i < n) points.push([x.call(self, d[i], i), y]);
2743
+ } else if (fy) {
2744
+ while (++i < n) points.push([x, y.call(self, d[i], i)]);
2745
+ } else {
2746
+ while (++i < n) points.push([x, y]);
2747
+ }
2748
+ return points;
2749
+ }
2750
+
2751
+ // The default `x` property, which references d[0].
2752
+ function d3_svg_lineX(d) {
2753
+ return d[0];
2754
+ }
2755
+
2756
+ // The default `y` property, which references d[1].
2757
+ function d3_svg_lineY(d) {
2758
+ return d[1];
2759
+ }
2760
+
2761
+ // The various interpolators supported by the `line` class.
2762
+ var d3_svg_lineInterpolators = {
2763
+ "linear": d3_svg_lineLinear,
2764
+ "step-before": d3_svg_lineStepBefore,
2765
+ "step-after": d3_svg_lineStepAfter,
2766
+ "basis": d3_svg_lineBasis,
2767
+ "basis-open": d3_svg_lineBasisOpen,
2768
+ "basis-closed": d3_svg_lineBasisClosed,
2769
+ "bundle": d3_svg_lineBundle,
2770
+ "cardinal": d3_svg_lineCardinal,
2771
+ "cardinal-open": d3_svg_lineCardinalOpen,
2772
+ "cardinal-closed": d3_svg_lineCardinalClosed,
2773
+ "monotone": d3_svg_lineMonotone
2774
+ };
2775
+
2776
+ // Linear interpolation; generates "L" commands.
2777
+ function d3_svg_lineLinear(points) {
2778
+ var path = [],
2779
+ i = 0,
2780
+ n = points.length,
2781
+ p = points[0];
2782
+ path.push(p[0], ",", p[1]);
2783
+ while (++i < n) path.push("L", (p = points[i])[0], ",", p[1]);
2784
+ return path.join("");
2785
+ }
2786
+
2787
+ // Step interpolation; generates "H" and "V" commands.
2788
+ function d3_svg_lineStepBefore(points) {
2789
+ var path = [],
2790
+ i = 0,
2791
+ n = points.length,
2792
+ p = points[0];
2793
+ path.push(p[0], ",", p[1]);
2794
+ while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]);
2795
+ return path.join("");
2796
+ }
2797
+
2798
+ // Step interpolation; generates "H" and "V" commands.
2799
+ function d3_svg_lineStepAfter(points) {
2800
+ var path = [],
2801
+ i = 0,
2802
+ n = points.length,
2803
+ p = points[0];
2804
+ path.push(p[0], ",", p[1]);
2805
+ while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]);
2806
+ return path.join("");
2807
+ }
2808
+
2809
+ // Open cardinal spline interpolation; generates "C" commands.
2810
+ function d3_svg_lineCardinalOpen(points, tension) {
2811
+ return points.length < 4
2812
+ ? d3_svg_lineLinear(points)
2813
+ : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1),
2814
+ d3_svg_lineCardinalTangents(points, tension));
2815
+ }
2816
+
2817
+ // Closed cardinal spline interpolation; generates "C" commands.
2818
+ function d3_svg_lineCardinalClosed(points, tension) {
2819
+ return points.length < 3
2820
+ ? d3_svg_lineLinear(points)
2821
+ : points[0] + d3_svg_lineHermite((points.push(points[0]), points),
2822
+ d3_svg_lineCardinalTangents([points[points.length - 2]]
2823
+ .concat(points, [points[1]]), tension));
2824
+ }
2825
+
2826
+ // Cardinal spline interpolation; generates "C" commands.
2827
+ function d3_svg_lineCardinal(points, tension, closed) {
2828
+ return points.length < 3
2829
+ ? d3_svg_lineLinear(points)
2830
+ : points[0] + d3_svg_lineHermite(points,
2831
+ d3_svg_lineCardinalTangents(points, tension));
2832
+ }
2833
+
2834
+ // Hermite spline construction; generates "C" commands.
2835
+ function d3_svg_lineHermite(points, tangents) {
2836
+ if (tangents.length < 1
2837
+ || (points.length != tangents.length
2838
+ && points.length != tangents.length + 2)) {
2839
+ return d3_svg_lineLinear(points);
2840
+ }
2841
+
2842
+ var quad = points.length != tangents.length,
2843
+ path = "",
2844
+ p0 = points[0],
2845
+ p = points[1],
2846
+ t0 = tangents[0],
2847
+ t = t0,
2848
+ pi = 1;
2849
+
2850
+ if (quad) {
2851
+ path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3)
2852
+ + "," + p[0] + "," + p[1];
2853
+ p0 = points[1];
2854
+ pi = 2;
2855
+ }
2856
+
2857
+ if (tangents.length > 1) {
2858
+ t = tangents[1];
2859
+ p = points[pi];
2860
+ pi++;
2861
+ path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1])
2862
+ + "," + (p[0] - t[0]) + "," + (p[1] - t[1])
2863
+ + "," + p[0] + "," + p[1];
2864
+ for (var i = 2; i < tangents.length; i++, pi++) {
2865
+ p = points[pi];
2866
+ t = tangents[i];
2867
+ path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1])
2868
+ + "," + p[0] + "," + p[1];
2869
+ }
2870
+ }
2871
+
2872
+ if (quad) {
2873
+ var lp = points[pi];
2874
+ path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3)
2875
+ + "," + lp[0] + "," + lp[1];
2876
+ }
2877
+
2878
+ return path;
2879
+ }
2880
+
2881
+ // Generates tangents for a cardinal spline.
2882
+ function d3_svg_lineCardinalTangents(points, tension) {
2883
+ var tangents = [],
2884
+ a = (1 - tension) / 2,
2885
+ p0,
2886
+ p1 = points[0],
2887
+ p2 = points[1],
2888
+ i = 1,
2889
+ n = points.length;
2890
+ while (++i < n) {
2891
+ p0 = p1;
2892
+ p1 = p2;
2893
+ p2 = points[i];
2894
+ tangents.push([a * (p2[0] - p0[0]), a * (p2[1] - p0[1])]);
2895
+ }
2896
+ return tangents;
2897
+ }
2898
+
2899
+ // B-spline interpolation; generates "C" commands.
2900
+ function d3_svg_lineBasis(points) {
2901
+ if (points.length < 3) return d3_svg_lineLinear(points);
2902
+ var path = [],
2903
+ i = 1,
2904
+ n = points.length,
2905
+ pi = points[0],
2906
+ x0 = pi[0],
2907
+ y0 = pi[1],
2908
+ px = [x0, x0, x0, (pi = points[1])[0]],
2909
+ py = [y0, y0, y0, pi[1]];
2910
+ path.push(x0, ",", y0);
2911
+ d3_svg_lineBasisBezier(path, px, py);
2912
+ while (++i < n) {
2913
+ pi = points[i];
2914
+ px.shift(); px.push(pi[0]);
2915
+ py.shift(); py.push(pi[1]);
2916
+ d3_svg_lineBasisBezier(path, px, py);
2917
+ }
2918
+ i = -1;
2919
+ while (++i < 2) {
2920
+ px.shift(); px.push(pi[0]);
2921
+ py.shift(); py.push(pi[1]);
2922
+ d3_svg_lineBasisBezier(path, px, py);
2923
+ }
2924
+ return path.join("");
2925
+ }
2926
+
2927
+ // Open B-spline interpolation; generates "C" commands.
2928
+ function d3_svg_lineBasisOpen(points) {
2929
+ if (points.length < 4) return d3_svg_lineLinear(points);
2930
+ var path = [],
2931
+ i = -1,
2932
+ n = points.length,
2933
+ pi,
2934
+ px = [0],
2935
+ py = [0];
2936
+ while (++i < 3) {
2937
+ pi = points[i];
2938
+ px.push(pi[0]);
2939
+ py.push(pi[1]);
2940
+ }
2941
+ path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px)
2942
+ + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py));
2943
+ --i; while (++i < n) {
2944
+ pi = points[i];
2945
+ px.shift(); px.push(pi[0]);
2946
+ py.shift(); py.push(pi[1]);
2947
+ d3_svg_lineBasisBezier(path, px, py);
2948
+ }
2949
+ return path.join("");
2950
+ }
2951
+
2952
+ // Closed B-spline interpolation; generates "C" commands.
2953
+ function d3_svg_lineBasisClosed(points) {
2954
+ var path,
2955
+ i = -1,
2956
+ n = points.length,
2957
+ m = n + 4,
2958
+ pi,
2959
+ px = [],
2960
+ py = [];
2961
+ while (++i < 4) {
2962
+ pi = points[i % n];
2963
+ px.push(pi[0]);
2964
+ py.push(pi[1]);
2965
+ }
2966
+ path = [
2967
+ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",",
2968
+ d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)
2969
+ ];
2970
+ --i; while (++i < m) {
2971
+ pi = points[i % n];
2972
+ px.shift(); px.push(pi[0]);
2973
+ py.shift(); py.push(pi[1]);
2974
+ d3_svg_lineBasisBezier(path, px, py);
2975
+ }
2976
+ return path.join("");
2977
+ }
2978
+
2979
+ function d3_svg_lineBundle(points, tension) {
2980
+ var n = points.length - 1,
2981
+ x0 = points[0][0],
2982
+ y0 = points[0][1],
2983
+ dx = points[n][0] - x0,
2984
+ dy = points[n][1] - y0,
2985
+ i = -1,
2986
+ p,
2987
+ t;
2988
+ while (++i <= n) {
2989
+ p = points[i];
2990
+ t = i / n;
2991
+ p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx);
2992
+ p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy);
2993
+ }
2994
+ return d3_svg_lineBasis(points);
2995
+ }
2996
+
2997
+ // Returns the dot product of the given four-element vectors.
2998
+ function d3_svg_lineDot4(a, b) {
2999
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
3000
+ }
3001
+
3002
+ // Matrix to transform basis (b-spline) control points to bezier
3003
+ // control points. Derived from FvD 11.2.8.
3004
+ var d3_svg_lineBasisBezier1 = [0, 2/3, 1/3, 0],
3005
+ d3_svg_lineBasisBezier2 = [0, 1/3, 2/3, 0],
3006
+ d3_svg_lineBasisBezier3 = [0, 1/6, 2/3, 1/6];
3007
+
3008
+ // Pushes a "C" Bézier curve onto the specified path array, given the
3009
+ // two specified four-element arrays which define the control points.
3010
+ function d3_svg_lineBasisBezier(path, x, y) {
3011
+ path.push(
3012
+ "C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x),
3013
+ ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y),
3014
+ ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x),
3015
+ ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y),
3016
+ ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x),
3017
+ ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y));
3018
+ }
3019
+
3020
+ // Computes the slope from points p0 to p1.
3021
+ function d3_svg_lineSlope(p0, p1) {
3022
+ return (p1[1] - p0[1]) / (p1[0] - p0[0]);
3023
+ }
3024
+
3025
+ // Compute three-point differences for the given points.
3026
+ // http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Finite_difference
3027
+ function d3_svg_lineFiniteDifferences(points) {
3028
+ var i = 0,
3029
+ j = points.length - 1,
3030
+ m = [],
3031
+ p0 = points[0],
3032
+ p1 = points[1],
3033
+ d = m[0] = d3_svg_lineSlope(p0, p1);
3034
+ while (++i < j) {
3035
+ m[i] = d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]));
3036
+ }
3037
+ m[i] = d;
3038
+ return m;
3039
+ }
3040
+
3041
+ // Interpolates the given points using Fritsch-Carlson Monotone cubic Hermite
3042
+ // interpolation. Returns an array of tangent vectors. For details, see
3043
+ // http://en.wikipedia.org/wiki/Monotone_cubic_interpolation
3044
+ function d3_svg_lineMonotoneTangents(points) {
3045
+ var tangents = [],
3046
+ d,
3047
+ a,
3048
+ b,
3049
+ s,
3050
+ m = d3_svg_lineFiniteDifferences(points),
3051
+ i = -1,
3052
+ j = points.length - 1;
3053
+
3054
+ // The first two steps are done by computing finite-differences:
3055
+ // 1. Compute the slopes of the secant lines between successive points.
3056
+ // 2. Initialize the tangents at every point as the average of the secants.
3057
+
3058
+ // Then, for each segment…
3059
+ while (++i < j) {
3060
+ d = d3_svg_lineSlope(points[i], points[i + 1]);
3061
+
3062
+ // 3. If two successive yk = y{k + 1} are equal (i.e., d is zero), then set
3063
+ // mk = m{k + 1} = 0 as the spline connecting these points must be flat to
3064
+ // preserve monotonicity. Ignore step 4 and 5 for those k.
3065
+
3066
+ if (Math.abs(d) < 1e-6) {
3067
+ m[i] = m[i + 1] = 0;
3068
+ } else {
3069
+ // 4. Let ak = mk / dk and bk = m{k + 1} / dk.
3070
+ a = m[i] / d;
3071
+ b = m[i + 1] / d;
3072
+
3073
+ // 5. Prevent overshoot and ensure monotonicity by restricting the
3074
+ // magnitude of vector <ak, bk> to a circle of radius 3.
3075
+ s = a * a + b * b;
3076
+ if (s > 9) {
3077
+ s = d * 3 / Math.sqrt(s);
3078
+ m[i] = s * a;
3079
+ m[i + 1] = s * b;
3080
+ }
3081
+ }
3082
+ }
3083
+
3084
+ // Compute the normalized tangent vector from the slopes. Note that if x is
3085
+ // not monotonic, it's possible that the slope will be infinite, so we protect
3086
+ // against NaN by setting the coordinate to zero.
3087
+ i = -1; while (++i <= j) {
3088
+ s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0])
3089
+ / (6 * (1 + m[i] * m[i]));
3090
+ tangents.push([s || 0, m[i] * s || 0]);
3091
+ }
3092
+
3093
+ return tangents;
3094
+ }
3095
+
3096
+ function d3_svg_lineMonotone(points) {
3097
+ return points.length < 3
3098
+ ? d3_svg_lineLinear(points)
3099
+ : points[0] +
3100
+ d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points));
3101
+ }
3102
+ d3.svg.line.radial = function() {
3103
+ var line = d3_svg_line(d3_svg_lineRadial);
3104
+ line.radius = line.x, delete line.x;
3105
+ line.angle = line.y, delete line.y;
3106
+ return line;
3107
+ };
3108
+
3109
+ function d3_svg_lineRadial(points) {
3110
+ var point,
3111
+ i = -1,
3112
+ n = points.length,
3113
+ r,
3114
+ a;
3115
+ while (++i < n) {
3116
+ point = points[i];
3117
+ r = point[0];
3118
+ a = point[1] + d3_svg_arcOffset;
3119
+ point[0] = r * Math.cos(a);
3120
+ point[1] = r * Math.sin(a);
3121
+ }
3122
+ return points;
3123
+ }
3124
+ function d3_svg_area(projection) {
3125
+ var x0 = d3_svg_lineX,
3126
+ x1 = d3_svg_lineX,
3127
+ y0 = 0,
3128
+ y1 = d3_svg_lineY,
3129
+ interpolate = "linear",
3130
+ interpolator = d3_svg_lineInterpolators[interpolate],
3131
+ tension = .7;
3132
+
3133
+ function area(d) {
3134
+ if (d.length < 1) return null;
3135
+ var points0 = d3_svg_linePoints(this, d, x0, y0),
3136
+ points1 = d3_svg_linePoints(this, d, x0 === x1 ? d3_svg_areaX(points0) : x1, y0 === y1 ? d3_svg_areaY(points0) : y1);
3137
+ return "M" + interpolator(projection(points1), tension)
3138
+ + "L" + interpolator(projection(points0.reverse()), tension)
3139
+ + "Z";
3140
+ }
3141
+
3142
+ area.x = function(x) {
3143
+ if (!arguments.length) return x1;
3144
+ x0 = x1 = x;
3145
+ return area;
3146
+ };
3147
+
3148
+ area.x0 = function(x) {
3149
+ if (!arguments.length) return x0;
3150
+ x0 = x;
3151
+ return area;
3152
+ };
3153
+
3154
+ area.x1 = function(x) {
3155
+ if (!arguments.length) return x1;
3156
+ x1 = x;
3157
+ return area;
3158
+ };
3159
+
3160
+ area.y = function(y) {
3161
+ if (!arguments.length) return y1;
3162
+ y0 = y1 = y;
3163
+ return area;
3164
+ };
3165
+
3166
+ area.y0 = function(y) {
3167
+ if (!arguments.length) return y0;
3168
+ y0 = y;
3169
+ return area;
3170
+ };
3171
+
3172
+ area.y1 = function(y) {
3173
+ if (!arguments.length) return y1;
3174
+ y1 = y;
3175
+ return area;
3176
+ };
3177
+
3178
+ area.interpolate = function(x) {
3179
+ if (!arguments.length) return interpolate;
3180
+ interpolator = d3_svg_lineInterpolators[interpolate = x];
3181
+ return area;
3182
+ };
3183
+
3184
+ area.tension = function(x) {
3185
+ if (!arguments.length) return tension;
3186
+ tension = x;
3187
+ return area;
3188
+ };
3189
+
3190
+ return area;
3191
+ }
3192
+
3193
+ d3.svg.area = function() {
3194
+ return d3_svg_area(Object);
3195
+ };
3196
+
3197
+ function d3_svg_areaX(points) {
3198
+ return function(d, i) {
3199
+ return points[i][0];
3200
+ };
3201
+ }
3202
+
3203
+ function d3_svg_areaY(points) {
3204
+ return function(d, i) {
3205
+ return points[i][1];
3206
+ };
3207
+ }
3208
+ d3.svg.area.radial = function() {
3209
+ var area = d3_svg_area(d3_svg_lineRadial);
3210
+ area.radius = area.x, delete area.x;
3211
+ area.innerRadius = area.x0, delete area.x0;
3212
+ area.outerRadius = area.x1, delete area.x1;
3213
+ area.angle = area.y, delete area.y;
3214
+ area.startAngle = area.y0, delete area.y0;
3215
+ area.endAngle = area.y1, delete area.y1;
3216
+ return area;
3217
+ };
3218
+ d3.svg.chord = function() {
3219
+ var source = d3_svg_chordSource,
3220
+ target = d3_svg_chordTarget,
3221
+ radius = d3_svg_chordRadius,
3222
+ startAngle = d3_svg_arcStartAngle,
3223
+ endAngle = d3_svg_arcEndAngle;
3224
+
3225
+ // TODO Allow control point to be customized.
3226
+
3227
+ function chord(d, i) {
3228
+ var s = subgroup(this, source, d, i),
3229
+ t = subgroup(this, target, d, i);
3230
+ return "M" + s.p0
3231
+ + arc(s.r, s.p1) + (equals(s, t)
3232
+ ? curve(s.r, s.p1, s.r, s.p0)
3233
+ : curve(s.r, s.p1, t.r, t.p0)
3234
+ + arc(t.r, t.p1)
3235
+ + curve(t.r, t.p1, s.r, s.p0))
3236
+ + "Z";
3237
+ }
3238
+
3239
+ function subgroup(self, f, d, i) {
3240
+ var subgroup = f.call(self, d, i),
3241
+ r = radius.call(self, subgroup, i),
3242
+ a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset,
3243
+ a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset;
3244
+ return {
3245
+ r: r,
3246
+ a0: a0,
3247
+ a1: a1,
3248
+ p0: [r * Math.cos(a0), r * Math.sin(a0)],
3249
+ p1: [r * Math.cos(a1), r * Math.sin(a1)]
3250
+ };
3251
+ }
3252
+
3253
+ function equals(a, b) {
3254
+ return a.a0 == b.a0 && a.a1 == b.a1;
3255
+ }
3256
+
3257
+ function arc(r, p) {
3258
+ return "A" + r + "," + r + " 0 0,1 " + p;
3259
+ }
3260
+
3261
+ function curve(r0, p0, r1, p1) {
3262
+ return "Q 0,0 " + p1;
3263
+ }
3264
+
3265
+ chord.radius = function(v) {
3266
+ if (!arguments.length) return radius;
3267
+ radius = d3.functor(v);
3268
+ return chord;
3269
+ };
3270
+
3271
+ chord.source = function(v) {
3272
+ if (!arguments.length) return source;
3273
+ source = d3.functor(v);
3274
+ return chord;
3275
+ };
3276
+
3277
+ chord.target = function(v) {
3278
+ if (!arguments.length) return target;
3279
+ target = d3.functor(v);
3280
+ return chord;
3281
+ };
3282
+
3283
+ chord.startAngle = function(v) {
3284
+ if (!arguments.length) return startAngle;
3285
+ startAngle = d3.functor(v);
3286
+ return chord;
3287
+ };
3288
+
3289
+ chord.endAngle = function(v) {
3290
+ if (!arguments.length) return endAngle;
3291
+ endAngle = d3.functor(v);
3292
+ return chord;
3293
+ };
3294
+
3295
+ return chord;
3296
+ };
3297
+
3298
+ function d3_svg_chordSource(d) {
3299
+ return d.source;
3300
+ }
3301
+
3302
+ function d3_svg_chordTarget(d) {
3303
+ return d.target;
3304
+ }
3305
+
3306
+ function d3_svg_chordRadius(d) {
3307
+ return d.radius;
3308
+ }
3309
+
3310
+ function d3_svg_chordStartAngle(d) {
3311
+ return d.startAngle;
3312
+ }
3313
+
3314
+ function d3_svg_chordEndAngle(d) {
3315
+ return d.endAngle;
3316
+ }
3317
+ d3.svg.diagonal = function() {
3318
+ var source = d3_svg_chordSource,
3319
+ target = d3_svg_chordTarget,
3320
+ projection = d3_svg_diagonalProjection;
3321
+
3322
+ function diagonal(d, i) {
3323
+ var p0 = source.call(this, d, i),
3324
+ p3 = target.call(this, d, i),
3325
+ m = (p0.y + p3.y) / 2,
3326
+ p = [p0, {x: p0.x, y: m}, {x: p3.x, y: m}, p3];
3327
+ p = p.map(projection);
3328
+ return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
3329
+ }
3330
+
3331
+ diagonal.source = function(x) {
3332
+ if (!arguments.length) return source;
3333
+ source = d3.functor(x);
3334
+ return diagonal;
3335
+ };
3336
+
3337
+ diagonal.target = function(x) {
3338
+ if (!arguments.length) return target;
3339
+ target = d3.functor(x);
3340
+ return diagonal;
3341
+ };
3342
+
3343
+ diagonal.projection = function(x) {
3344
+ if (!arguments.length) return projection;
3345
+ projection = x;
3346
+ return diagonal;
3347
+ };
3348
+
3349
+ return diagonal;
3350
+ };
3351
+
3352
+ function d3_svg_diagonalProjection(d) {
3353
+ return [d.x, d.y];
3354
+ }
3355
+ d3.svg.diagonal.radial = function() {
3356
+ var diagonal = d3.svg.diagonal(),
3357
+ projection = d3_svg_diagonalProjection,
3358
+ projection_ = diagonal.projection;
3359
+
3360
+ diagonal.projection = function(x) {
3361
+ return arguments.length
3362
+ ? projection_(d3_svg_diagonalRadialProjection(projection = x))
3363
+ : projection;
3364
+ };
3365
+
3366
+ return diagonal;
3367
+ };
3368
+
3369
+ function d3_svg_diagonalRadialProjection(projection) {
3370
+ return function() {
3371
+ var d = projection.apply(this, arguments),
3372
+ r = d[0],
3373
+ a = d[1] + d3_svg_arcOffset;
3374
+ return [r * Math.cos(a), r * Math.sin(a)];
3375
+ };
3376
+ }
3377
+ d3.svg.mouse = function(container) {
3378
+ return d3_svg_mousePoint(container, d3.event);
3379
+ };
3380
+
3381
+ // https://bugs.webkit.org/show_bug.cgi?id=44083
3382
+ var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0;
3383
+
3384
+ function d3_svg_mousePoint(container, e) {
3385
+ var point = (container.ownerSVGElement || container).createSVGPoint();
3386
+ if ((d3_mouse_bug44083 < 0) && (window.scrollX || window.scrollY)) {
3387
+ var svg = d3.select(document.body)
3388
+ .append("svg:svg")
3389
+ .style("position", "absolute")
3390
+ .style("top", 0)
3391
+ .style("left", 0);
3392
+ var ctm = svg[0][0].getScreenCTM();
3393
+ d3_mouse_bug44083 = !(ctm.f || ctm.e);
3394
+ svg.remove();
3395
+ }
3396
+ if (d3_mouse_bug44083) {
3397
+ point.x = e.pageX;
3398
+ point.y = e.pageY;
3399
+ } else {
3400
+ point.x = e.clientX;
3401
+ point.y = e.clientY;
3402
+ }
3403
+ point = point.matrixTransform(container.getScreenCTM().inverse());
3404
+ return [point.x, point.y];
3405
+ };
3406
+ d3.svg.touches = function(container) {
3407
+ var touches = d3.event.touches;
3408
+ return touches ? Array.prototype.map.call(touches, function(touch) {
3409
+ var point = d3_svg_mousePoint(container, touch);
3410
+ point.identifier = touch.identifier;
3411
+ return point;
3412
+ }) : [];
3413
+ };
3414
+ d3.svg.symbol = function() {
3415
+ var type = d3_svg_symbolType,
3416
+ size = d3_svg_symbolSize;
3417
+
3418
+ function symbol(d, i) {
3419
+ return (d3_svg_symbols[type.call(this, d, i)]
3420
+ || d3_svg_symbols.circle)
3421
+ (size.call(this, d, i));
3422
+ }
3423
+
3424
+ symbol.type = function(x) {
3425
+ if (!arguments.length) return type;
3426
+ type = d3.functor(x);
3427
+ return symbol;
3428
+ };
3429
+
3430
+ // size of symbol in square pixels
3431
+ symbol.size = function(x) {
3432
+ if (!arguments.length) return size;
3433
+ size = d3.functor(x);
3434
+ return symbol;
3435
+ };
3436
+
3437
+ return symbol;
3438
+ };
3439
+
3440
+ function d3_svg_symbolSize() {
3441
+ return 64;
3442
+ }
3443
+
3444
+ function d3_svg_symbolType() {
3445
+ return "circle";
3446
+ }
3447
+
3448
+ // TODO cross-diagonal?
3449
+ var d3_svg_symbols = {
3450
+ "circle": function(size) {
3451
+ var r = Math.sqrt(size / Math.PI);
3452
+ return "M0," + r
3453
+ + "A" + r + "," + r + " 0 1,1 0," + (-r)
3454
+ + "A" + r + "," + r + " 0 1,1 0," + r
3455
+ + "Z";
3456
+ },
3457
+ "cross": function(size) {
3458
+ var r = Math.sqrt(size / 5) / 2;
3459
+ return "M" + -3 * r + "," + -r
3460
+ + "H" + -r
3461
+ + "V" + -3 * r
3462
+ + "H" + r
3463
+ + "V" + -r
3464
+ + "H" + 3 * r
3465
+ + "V" + r
3466
+ + "H" + r
3467
+ + "V" + 3 * r
3468
+ + "H" + -r
3469
+ + "V" + r
3470
+ + "H" + -3 * r
3471
+ + "Z";
3472
+ },
3473
+ "diamond": function(size) {
3474
+ var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)),
3475
+ rx = ry * d3_svg_symbolTan30;
3476
+ return "M0," + -ry
3477
+ + "L" + rx + ",0"
3478
+ + " 0," + ry
3479
+ + " " + -rx + ",0"
3480
+ + "Z";
3481
+ },
3482
+ "square": function(size) {
3483
+ var r = Math.sqrt(size) / 2;
3484
+ return "M" + -r + "," + -r
3485
+ + "L" + r + "," + -r
3486
+ + " " + r + "," + r
3487
+ + " " + -r + "," + r
3488
+ + "Z";
3489
+ },
3490
+ "triangle-down": function(size) {
3491
+ var rx = Math.sqrt(size / d3_svg_symbolSqrt3),
3492
+ ry = rx * d3_svg_symbolSqrt3 / 2;
3493
+ return "M0," + ry
3494
+ + "L" + rx +"," + -ry
3495
+ + " " + -rx + "," + -ry
3496
+ + "Z";
3497
+ },
3498
+ "triangle-up": function(size) {
3499
+ var rx = Math.sqrt(size / d3_svg_symbolSqrt3),
3500
+ ry = rx * d3_svg_symbolSqrt3 / 2;
3501
+ return "M0," + -ry
3502
+ + "L" + rx +"," + ry
3503
+ + " " + -rx + "," + ry
3504
+ + "Z";
3505
+ }
3506
+ };
3507
+
3508
+ d3.svg.symbolTypes = d3.keys(d3_svg_symbols);
3509
+
3510
+ var d3_svg_symbolSqrt3 = Math.sqrt(3),
3511
+ d3_svg_symbolTan30 = Math.tan(30 * Math.PI / 180);
3512
+ d3.svg.axis = function() {
3513
+ var scale = d3.scale.linear(),
3514
+ orient = "bottom",
3515
+ tickMajorSize = 6,
3516
+ tickMinorSize = 6,
3517
+ tickEndSize = 6,
3518
+ tickPadding = 3,
3519
+ tickArguments_ = [10],
3520
+ tickFormat_,
3521
+ tickSubdivide = 0;
3522
+
3523
+ function axis(selection) {
3524
+ selection.each(function(d, i, j) {
3525
+ var g = d3.select(this);
3526
+
3527
+ // Ticks.
3528
+ var ticks = scale.ticks.apply(scale, tickArguments_),
3529
+ tickFormat = tickFormat_ == null ? scale.tickFormat.apply(scale, tickArguments_) : tickFormat_;
3530
+
3531
+ // Minor ticks.
3532
+ var subticks = d3_svg_axisSubdivide(scale, ticks, tickSubdivide),
3533
+ subtick = g.selectAll(".minor").data(subticks, String),
3534
+ subtickEnter = subtick.enter().insert("svg:line", "g").attr("class", "tick minor").style("opacity", 1e-6),
3535
+ subtickExit = transition(subtick.exit()).style("opacity", 1e-6).remove(),
3536
+ subtickUpdate = transition(subtick).style("opacity", 1);
3537
+
3538
+ // Major ticks.
3539
+ var tick = g.selectAll("g").data(ticks, String),
3540
+ tickEnter = tick.enter().insert("svg:g", "path").style("opacity", 1e-6),
3541
+ tickExit = transition(tick.exit()).style("opacity", 1e-6).remove(),
3542
+ tickUpdate = transition(tick).style("opacity", 1),
3543
+ tickTransform;
3544
+
3545
+ // Domain.
3546
+ var range = d3_scaleExtent(scale.range()),
3547
+ path = g.selectAll(".domain").data([,]),
3548
+ pathEnter = path.enter().append("svg:path").attr("class", "domain"),
3549
+ pathUpdate = transition(path);
3550
+
3551
+ // Stash the new scale and grab the old scale.
3552
+ var scale0 = this.__chart__ || scale;
3553
+ this.__chart__ = scale.copy();
3554
+
3555
+ tickEnter.append("svg:line").attr("class", "tick");
3556
+ tickEnter.append("svg:text");
3557
+ tickUpdate.select("text").text(tickFormat);
3558
+
3559
+ switch (orient) {
3560
+ case "bottom": {
3561
+ tickTransform = d3_svg_axisX;
3562
+ subtickUpdate.attr("y2", tickMinorSize);
3563
+ tickEnter.select("text").attr("dy", ".71em").attr("text-anchor", "middle");
3564
+ tickUpdate.select("line").attr("y2", tickMajorSize);
3565
+ tickUpdate.select("text").attr("y", Math.max(tickMajorSize, 0) + tickPadding);
3566
+ pathUpdate.attr("d", "M" + range[0] + "," + tickEndSize + "V0H" + range[1] + "V" + tickEndSize);
3567
+ break;
3568
+ }
3569
+ case "top": {
3570
+ tickTransform = d3_svg_axisX;
3571
+ subtickUpdate.attr("y2", -tickMinorSize);
3572
+ tickEnter.select("text").attr("text-anchor", "middle");
3573
+ tickUpdate.select("line").attr("y2", -tickMajorSize);
3574
+ tickUpdate.select("text").attr("y", -(Math.max(tickMajorSize, 0) + tickPadding));
3575
+ pathUpdate.attr("d", "M" + range[0] + "," + -tickEndSize + "V0H" + range[1] + "V" + -tickEndSize);
3576
+ break;
3577
+ }
3578
+ case "left": {
3579
+ tickTransform = d3_svg_axisY;
3580
+ subtickUpdate.attr("x2", -tickMinorSize);
3581
+ tickEnter.select("text").attr("dy", ".32em").attr("text-anchor", "end");
3582
+ tickUpdate.select("line").attr("x2", -tickMajorSize);
3583
+ tickUpdate.select("text").attr("x", -(Math.max(tickMajorSize, 0) + tickPadding));
3584
+ pathUpdate.attr("d", "M" + -tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + -tickEndSize);
3585
+ break;
3586
+ }
3587
+ case "right": {
3588
+ tickTransform = d3_svg_axisY;
3589
+ subtickUpdate.attr("x2", tickMinorSize);
3590
+ tickEnter.select("text").attr("dy", ".32em");
3591
+ tickUpdate.select("line").attr("x2", tickMajorSize);
3592
+ tickUpdate.select("text").attr("x", Math.max(tickMajorSize, 0) + tickPadding);
3593
+ pathUpdate.attr("d", "M" + tickEndSize + "," + range[0] + "H0V" + range[1] + "H" + tickEndSize);
3594
+ break;
3595
+ }
3596
+ }
3597
+
3598
+ tickEnter.call(tickTransform, scale0);
3599
+ tickUpdate.call(tickTransform, scale);
3600
+ tickExit.call(tickTransform, scale);
3601
+
3602
+ subtickEnter.call(tickTransform, scale0);
3603
+ subtickUpdate.call(tickTransform, scale);
3604
+ subtickExit.call(tickTransform, scale);
3605
+
3606
+ function transition(o) {
3607
+ return selection.delay ? o.transition()
3608
+ .delay(selection[j][i].delay)
3609
+ .duration(selection[j][i].duration)
3610
+ .ease(selection.ease()) : o;
3611
+ }
3612
+ });
3613
+ }
3614
+
3615
+ axis.scale = function(x) {
3616
+ if (!arguments.length) return scale;
3617
+ scale = x;
3618
+ return axis;
3619
+ };
3620
+
3621
+ axis.orient = function(x) {
3622
+ if (!arguments.length) return orient;
3623
+ orient = x;
3624
+ return axis;
3625
+ };
3626
+
3627
+ axis.ticks = function() {
3628
+ if (!arguments.length) return tickArguments_;
3629
+ tickArguments_ = arguments;
3630
+ return axis;
3631
+ };
3632
+
3633
+ axis.tickFormat = function(x) {
3634
+ if (!arguments.length) return tickFormat_;
3635
+ tickFormat_ = x;
3636
+ return axis;
3637
+ };
3638
+
3639
+ axis.tickSize = function(x, y, z) {
3640
+ if (!arguments.length) return tickMajorSize;
3641
+ var n = arguments.length - 1;
3642
+ tickMajorSize = +x;
3643
+ tickMinorSize = n > 1 ? +y : tickMajorSize;
3644
+ tickEndSize = n > 0 ? +arguments[n] : tickMajorSize;
3645
+ return axis;
3646
+ };
3647
+
3648
+ axis.tickPadding = function(x) {
3649
+ if (!arguments.length) return tickPadding;
3650
+ tickPadding = +x;
3651
+ return axis;
3652
+ };
3653
+
3654
+ axis.tickSubdivide = function(x) {
3655
+ if (!arguments.length) return tickSubdivide;
3656
+ tickSubdivide = +x;
3657
+ return axis;
3658
+ };
3659
+
3660
+ return axis;
3661
+ };
3662
+
3663
+ function d3_svg_axisX(selection, x) {
3664
+ selection.attr("transform", function(d) { return "translate(" + x(d) + ",0)"; });
3665
+ }
3666
+
3667
+ function d3_svg_axisY(selection, y) {
3668
+ selection.attr("transform", function(d) { return "translate(0," + y(d) + ")"; });
3669
+ }
3670
+
3671
+ function d3_svg_axisSubdivide(scale, ticks, m) {
3672
+ subticks = [];
3673
+ if (m && ticks.length > 1) {
3674
+ var extent = d3_scaleExtent(scale.domain()),
3675
+ subticks,
3676
+ i = -1,
3677
+ n = ticks.length,
3678
+ d = (ticks[1] - ticks[0]) / ++m,
3679
+ j,
3680
+ v;
3681
+ while (++i < n) {
3682
+ for (j = m; --j > 0;) {
3683
+ if ((v = +ticks[i] - j * d) >= extent[0]) {
3684
+ subticks.push(v);
3685
+ }
3686
+ }
3687
+ }
3688
+ for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1];) {
3689
+ subticks.push(v);
3690
+ }
3691
+ }
3692
+ return subticks;
3693
+ }
3694
+ d3.behavior = {};
3695
+ d3.behavior.drag = function() {
3696
+ var event = d3.dispatch("drag", "dragstart", "dragend");
3697
+
3698
+ function drag() {
3699
+ this
3700
+ .on("mousedown.drag", mousedown)
3701
+ .on("touchstart.drag", mousedown);
3702
+
3703
+ d3.select(window)
3704
+ .on("mousemove.drag", d3_behavior_dragMove)
3705
+ .on("touchmove.drag", d3_behavior_dragMove)
3706
+ .on("mouseup.drag", d3_behavior_dragUp, true)
3707
+ .on("touchend.drag", d3_behavior_dragUp, true)
3708
+ .on("click.drag", d3_behavior_dragClick, true);
3709
+ }
3710
+
3711
+ // snapshot the local context for subsequent dispatch
3712
+ function start() {
3713
+ d3_behavior_dragEvent = event;
3714
+ d3_behavior_dragOffset = d3_behavior_dragPoint((d3_behavior_dragTarget = this).parentNode);
3715
+ d3_behavior_dragMoved = 0;
3716
+ d3_behavior_dragArguments = arguments;
3717
+ }
3718
+
3719
+ function mousedown() {
3720
+ start.apply(this, arguments);
3721
+ d3_behavior_dragDispatch("dragstart");
3722
+ }
3723
+
3724
+ drag.on = function(type, listener) {
3725
+ event[type].add(listener);
3726
+ return drag;
3727
+ };
3728
+
3729
+ return drag;
3730
+ };
3731
+
3732
+ var d3_behavior_dragEvent,
3733
+ d3_behavior_dragTarget,
3734
+ d3_behavior_dragArguments,
3735
+ d3_behavior_dragOffset,
3736
+ d3_behavior_dragMoved,
3737
+ d3_behavior_dragStopClick;
3738
+
3739
+ function d3_behavior_dragDispatch(type) {
3740
+ var o = d3.event, p = d3_behavior_dragTarget.parentNode, dx = 0, dy = 0;
3741
+
3742
+ if (p) {
3743
+ p = d3_behavior_dragPoint(p);
3744
+ dx = p[0] - d3_behavior_dragOffset[0];
3745
+ dy = p[1] - d3_behavior_dragOffset[1];
3746
+ d3_behavior_dragOffset = p;
3747
+ d3_behavior_dragMoved |= dx | dy;
3748
+ }
3749
+
3750
+ try {
3751
+ d3.event = {dx: dx, dy: dy};
3752
+ d3_behavior_dragEvent[type].dispatch.apply(d3_behavior_dragTarget, d3_behavior_dragArguments);
3753
+ } finally {
3754
+ d3.event = o;
3755
+ }
3756
+
3757
+ o.preventDefault();
3758
+ }
3759
+
3760
+ function d3_behavior_dragPoint(container) {
3761
+ return d3.event.touches
3762
+ ? d3.svg.touches(container)[0]
3763
+ : d3.svg.mouse(container);
3764
+ }
3765
+
3766
+ function d3_behavior_dragMove() {
3767
+ if (!d3_behavior_dragTarget) return;
3768
+ var parent = d3_behavior_dragTarget.parentNode;
3769
+
3770
+ // O NOES! The drag element was removed from the DOM.
3771
+ if (!parent) return d3_behavior_dragUp();
3772
+
3773
+ d3_behavior_dragDispatch("drag");
3774
+ d3_behavior_dragCancel();
3775
+ }
3776
+
3777
+ function d3_behavior_dragUp() {
3778
+ if (!d3_behavior_dragTarget) return;
3779
+ d3_behavior_dragDispatch("dragend");
3780
+ d3_behavior_dragTarget = null;
3781
+
3782
+ // If the node was moved, prevent the mouseup from propagating.
3783
+ // Also prevent the subsequent click from propagating (e.g., for anchors).
3784
+ if (d3_behavior_dragMoved) {
3785
+ d3_behavior_dragStopClick = true;
3786
+ d3_behavior_dragCancel();
3787
+ }
3788
+ }
3789
+
3790
+ function d3_behavior_dragClick() {
3791
+ if (d3_behavior_dragStopClick) {
3792
+ d3_behavior_dragCancel();
3793
+ d3_behavior_dragStopClick = false;
3794
+ }
3795
+ }
3796
+
3797
+ function d3_behavior_dragCancel() {
3798
+ d3.event.stopPropagation();
3799
+ d3.event.preventDefault();
3800
+ }
3801
+ // TODO unbind zoom behavior?
3802
+ // TODO unbind listener?
3803
+ d3.behavior.zoom = function() {
3804
+ var xyz = [0, 0, 0],
3805
+ event = d3.dispatch("zoom");
3806
+
3807
+ function zoom() {
3808
+ this
3809
+ .on("mousedown.zoom", mousedown)
3810
+ .on("mousewheel.zoom", mousewheel)
3811
+ .on("DOMMouseScroll.zoom", mousewheel)
3812
+ .on("dblclick.zoom", dblclick)
3813
+ .on("touchstart.zoom", touchstart);
3814
+
3815
+ d3.select(window)
3816
+ .on("mousemove.zoom", d3_behavior_zoomMousemove)
3817
+ .on("mouseup.zoom", d3_behavior_zoomMouseup)
3818
+ .on("touchmove.zoom", d3_behavior_zoomTouchmove)
3819
+ .on("touchend.zoom", d3_behavior_zoomTouchup)
3820
+ .on("click.zoom", d3_behavior_zoomClick, true);
3821
+ }
3822
+
3823
+ // snapshot the local context for subsequent dispatch
3824
+ function start() {
3825
+ d3_behavior_zoomXyz = xyz;
3826
+ d3_behavior_zoomDispatch = event.zoom.dispatch;
3827
+ d3_behavior_zoomTarget = this;
3828
+ d3_behavior_zoomArguments = arguments;
3829
+ }
3830
+
3831
+ function mousedown() {
3832
+ start.apply(this, arguments);
3833
+ d3_behavior_zoomPanning = d3_behavior_zoomLocation(d3.svg.mouse(d3_behavior_zoomTarget));
3834
+ d3_behavior_zoomMoved = false;
3835
+ d3.event.preventDefault();
3836
+ window.focus();
3837
+ }
3838
+
3839
+ // store starting mouse location
3840
+ function mousewheel() {
3841
+ start.apply(this, arguments);
3842
+ if (!d3_behavior_zoomZooming) d3_behavior_zoomZooming = d3_behavior_zoomLocation(d3.svg.mouse(d3_behavior_zoomTarget));
3843
+ d3_behavior_zoomTo(d3_behavior_zoomDelta() + xyz[2], d3.svg.mouse(d3_behavior_zoomTarget), d3_behavior_zoomZooming);
3844
+ }
3845
+
3846
+ function dblclick() {
3847
+ start.apply(this, arguments);
3848
+ var mouse = d3.svg.mouse(d3_behavior_zoomTarget);
3849
+ d3_behavior_zoomTo(d3.event.shiftKey ? Math.ceil(xyz[2] - 1) : Math.floor(xyz[2] + 1), mouse, d3_behavior_zoomLocation(mouse));
3850
+ }
3851
+
3852
+ // doubletap detection
3853
+ function touchstart() {
3854
+ start.apply(this, arguments);
3855
+ var touches = d3_behavior_zoomTouchup(),
3856
+ touch,
3857
+ now = Date.now();
3858
+ if ((touches.length === 1) && (now - d3_behavior_zoomLast < 300)) {
3859
+ d3_behavior_zoomTo(1 + Math.floor(xyz[2]), touch = touches[0], d3_behavior_zoomLocations[touch.identifier]);
3860
+ }
3861
+ d3_behavior_zoomLast = now;
3862
+ }
3863
+
3864
+ zoom.on = function(type, listener) {
3865
+ event[type].add(listener);
3866
+ return zoom;
3867
+ };
3868
+
3869
+ return zoom;
3870
+ };
3871
+
3872
+ var d3_behavior_zoomDiv,
3873
+ d3_behavior_zoomPanning,
3874
+ d3_behavior_zoomZooming,
3875
+ d3_behavior_zoomLocations = {}, // identifier -> location
3876
+ d3_behavior_zoomLast = 0,
3877
+ d3_behavior_zoomXyz,
3878
+ d3_behavior_zoomDispatch,
3879
+ d3_behavior_zoomTarget,
3880
+ d3_behavior_zoomArguments,
3881
+ d3_behavior_zoomMoved,
3882
+ d3_behavior_zoomStopClick;
3883
+
3884
+ function d3_behavior_zoomLocation(point) {
3885
+ return [
3886
+ point[0] - d3_behavior_zoomXyz[0],
3887
+ point[1] - d3_behavior_zoomXyz[1],
3888
+ d3_behavior_zoomXyz[2]
3889
+ ];
3890
+ }
3891
+
3892
+ // detect the pixels that would be scrolled by this wheel event
3893
+ function d3_behavior_zoomDelta() {
3894
+
3895
+ // mousewheel events are totally broken!
3896
+ // https://bugs.webkit.org/show_bug.cgi?id=40441
3897
+ // not only that, but Chrome and Safari differ in re. to acceleration!
3898
+ if (!d3_behavior_zoomDiv) {
3899
+ d3_behavior_zoomDiv = d3.select("body").append("div")
3900
+ .style("visibility", "hidden")
3901
+ .style("top", 0)
3902
+ .style("height", 0)
3903
+ .style("width", 0)
3904
+ .style("overflow-y", "scroll")
3905
+ .append("div")
3906
+ .style("height", "2000px")
3907
+ .node().parentNode;
3908
+ }
3909
+
3910
+ var e = d3.event, delta;
3911
+ try {
3912
+ d3_behavior_zoomDiv.scrollTop = 1000;
3913
+ d3_behavior_zoomDiv.dispatchEvent(e);
3914
+ delta = 1000 - d3_behavior_zoomDiv.scrollTop;
3915
+ } catch (error) {
3916
+ delta = e.wheelDelta || (-e.detail * 5);
3917
+ }
3918
+
3919
+ return delta * .005;
3920
+ }
3921
+
3922
+ // Note: Since we don't rotate, it's possible for the touches to become
3923
+ // slightly detached from their original positions. Thus, we recompute the
3924
+ // touch points on touchend as well as touchstart!
3925
+ function d3_behavior_zoomTouchup() {
3926
+ var touches = d3.svg.touches(d3_behavior_zoomTarget),
3927
+ i = -1,
3928
+ n = touches.length,
3929
+ touch;
3930
+ while (++i < n) d3_behavior_zoomLocations[(touch = touches[i]).identifier] = d3_behavior_zoomLocation(touch);
3931
+ return touches;
3932
+ }
3933
+
3934
+ function d3_behavior_zoomTouchmove() {
3935
+ var touches = d3.svg.touches(d3_behavior_zoomTarget);
3936
+ switch (touches.length) {
3937
+
3938
+ // single-touch pan
3939
+ case 1: {
3940
+ var touch = touches[0];
3941
+ d3_behavior_zoomTo(d3_behavior_zoomXyz[2], touch, d3_behavior_zoomLocations[touch.identifier]);
3942
+ break;
3943
+ }
3944
+
3945
+ // double-touch pan + zoom
3946
+ case 2: {
3947
+ var p0 = touches[0],
3948
+ p1 = touches[1],
3949
+ p2 = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2],
3950
+ l0 = d3_behavior_zoomLocations[p0.identifier],
3951
+ l1 = d3_behavior_zoomLocations[p1.identifier],
3952
+ l2 = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2, l0[2]];
3953
+ d3_behavior_zoomTo(Math.log(d3.event.scale) / Math.LN2 + l0[2], p2, l2);
3954
+ break;
3955
+ }
3956
+ }
3957
+ }
3958
+
3959
+ function d3_behavior_zoomMousemove() {
3960
+ d3_behavior_zoomZooming = null;
3961
+ if (d3_behavior_zoomPanning) {
3962
+ d3_behavior_zoomMoved = true;
3963
+ d3_behavior_zoomTo(d3_behavior_zoomXyz[2], d3.svg.mouse(d3_behavior_zoomTarget), d3_behavior_zoomPanning);
3964
+ }
3965
+ }
3966
+
3967
+ function d3_behavior_zoomMouseup() {
3968
+ if (d3_behavior_zoomPanning) {
3969
+ if (d3_behavior_zoomMoved) d3_behavior_zoomStopClick = true;
3970
+ d3_behavior_zoomMousemove();
3971
+ d3_behavior_zoomPanning = null;
3972
+ }
3973
+ }
3974
+
3975
+ function d3_behavior_zoomClick() {
3976
+ if (d3_behavior_zoomStopClick) {
3977
+ d3.event.stopPropagation();
3978
+ d3.event.preventDefault();
3979
+ d3_behavior_zoomStopClick = false;
3980
+ }
3981
+ }
3982
+
3983
+ function d3_behavior_zoomTo(z, x0, x1) {
3984
+ var K = Math.pow(2, (d3_behavior_zoomXyz[2] = z) - x1[2]),
3985
+ x = d3_behavior_zoomXyz[0] = x0[0] - K * x1[0],
3986
+ y = d3_behavior_zoomXyz[1] = x0[1] - K * x1[1],
3987
+ o = d3.event, // Events can be reentrant (e.g., focus).
3988
+ k = Math.pow(2, z);
3989
+
3990
+ d3.event = {
3991
+ scale: k,
3992
+ translate: [x, y],
3993
+ transform: function(sx, sy) {
3994
+ if (sx) transform(sx, x);
3995
+ if (sy) transform(sy, y);
3996
+ }
3997
+ };
3998
+
3999
+ function transform(scale, o) {
4000
+ var domain = scale.__domain || (scale.__domain = scale.domain()),
4001
+ range = scale.range().map(function(v) { return (v - o) / k; });
4002
+ scale.domain(domain).domain(range.map(scale.invert));
4003
+ }
4004
+
4005
+ try {
4006
+ d3_behavior_zoomDispatch.apply(d3_behavior_zoomTarget, d3_behavior_zoomArguments);
4007
+ } finally {
4008
+ d3.event = o;
4009
+ }
4010
+
4011
+ o.preventDefault();
4012
+ }
4013
+ })();