wukong 3.0.0.pre → 3.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (476) hide show
  1. data/.gitignore +46 -33
  2. data/.gitmodules +3 -0
  3. data/.rspec +1 -1
  4. data/.travis.yml +8 -1
  5. data/.yardopts +0 -13
  6. data/Guardfile +4 -6
  7. data/{LICENSE.textile → LICENSE.md} +43 -55
  8. data/README-old.md +422 -0
  9. data/README.md +279 -418
  10. data/Rakefile +21 -5
  11. data/TODO.md +6 -6
  12. data/bin/wu-clean-encoding +31 -0
  13. data/bin/wu-lign +2 -2
  14. data/bin/wu-local +69 -0
  15. data/bin/wu-server +70 -0
  16. data/examples/Gemfile +38 -0
  17. data/examples/README.md +9 -0
  18. data/examples/dataflow/apache_log_line.rb +64 -25
  19. data/examples/dataflow/fibonacci_series.rb +101 -0
  20. data/examples/dataflow/parse_apache_logs.rb +37 -7
  21. data/examples/{dataflow.rb → dataflow/scraper_macro_flow.rb} +0 -0
  22. data/examples/dataflow/simple.rb +4 -4
  23. data/examples/geo.rb +4 -0
  24. data/examples/geo/geo_grids.numbers +0 -0
  25. data/examples/geo/geolocated.rb +331 -0
  26. data/examples/geo/quadtile.rb +69 -0
  27. data/examples/geo/spec/geolocated_spec.rb +247 -0
  28. data/examples/geo/tile_fetcher.rb +77 -0
  29. data/examples/graph/minimum_spanning_tree.rb +61 -61
  30. data/examples/jabberwocky.txt +36 -0
  31. data/examples/models/wikipedia.rb +20 -0
  32. data/examples/munging/Gemfile +8 -0
  33. data/examples/munging/airline_flights/airline.rb +57 -0
  34. data/examples/munging/airline_flights/airline_flights.rake +83 -0
  35. data/{lib/wukong/settings.rb → examples/munging/airline_flights/airplane.rb} +0 -0
  36. data/examples/munging/airline_flights/airport.rb +211 -0
  37. data/examples/munging/airline_flights/airport_id_unification.rb +129 -0
  38. data/examples/munging/airline_flights/airport_ok_chars.rb +4 -0
  39. data/examples/munging/airline_flights/flight.rb +156 -0
  40. data/examples/munging/airline_flights/models.rb +4 -0
  41. data/examples/munging/airline_flights/parse.rb +26 -0
  42. data/examples/munging/airline_flights/reconcile_airports.rb +142 -0
  43. data/examples/munging/airline_flights/route.rb +35 -0
  44. data/examples/munging/airline_flights/tasks.rake +83 -0
  45. data/examples/munging/airline_flights/timezone_fixup.rb +62 -0
  46. data/examples/munging/airline_flights/topcities.rb +167 -0
  47. data/examples/munging/airports/40_wbans.txt +40 -0
  48. data/examples/munging/airports/filter_weather_reports.rb +37 -0
  49. data/examples/munging/airports/join.pig +31 -0
  50. data/examples/munging/airports/to_tsv.rb +33 -0
  51. data/examples/munging/airports/usa_wbans.pig +19 -0
  52. data/examples/munging/airports/usa_wbans.txt +2157 -0
  53. data/examples/munging/airports/wbans.pig +19 -0
  54. data/examples/munging/airports/wbans.txt +2310 -0
  55. data/examples/munging/geo/geo_json.rb +54 -0
  56. data/examples/munging/geo/geo_models.rb +69 -0
  57. data/examples/munging/geo/geonames_models.rb +78 -0
  58. data/examples/munging/geo/iso_codes.rb +172 -0
  59. data/examples/munging/geo/reconcile_countries.rb +124 -0
  60. data/examples/munging/geo/tasks.rake +71 -0
  61. data/examples/munging/rake_helper.rb +62 -0
  62. data/examples/munging/weather/.gitignore +1 -0
  63. data/examples/munging/weather/Gemfile +4 -0
  64. data/examples/munging/weather/Rakefile +28 -0
  65. data/examples/munging/weather/extract_ish.rb +13 -0
  66. data/examples/munging/weather/models/weather.rb +119 -0
  67. data/examples/munging/weather/utils/noaa_downloader.rb +46 -0
  68. data/examples/munging/wikipedia/README.md +34 -0
  69. data/examples/munging/wikipedia/Rakefile +193 -0
  70. data/examples/munging/wikipedia/articles/extract_articles-parsed.rb +79 -0
  71. data/examples/munging/wikipedia/articles/extract_articles-templated.rb +136 -0
  72. data/examples/munging/wikipedia/articles/textualize_articles.rb +54 -0
  73. data/examples/munging/wikipedia/articles/verify_structure.rb +43 -0
  74. data/examples/munging/wikipedia/articles/wp2txt-LICENSE.txt +22 -0
  75. data/examples/munging/wikipedia/articles/wp2txt_article.rb +259 -0
  76. data/examples/munging/wikipedia/articles/wp2txt_utils.rb +452 -0
  77. data/examples/munging/wikipedia/dbpedia/dbpedia_common.rb +4 -0
  78. data/examples/munging/wikipedia/dbpedia/dbpedia_extract_geocoordinates.rb +78 -0
  79. data/examples/munging/wikipedia/dbpedia/extract_links.rb +193 -0
  80. data/examples/munging/wikipedia/dbpedia/sameas_extractor.rb +20 -0
  81. data/examples/munging/wikipedia/n1_subuniverse/n1_nodes.pig +18 -0
  82. data/examples/munging/wikipedia/page_metadata/extract_page_metadata.rb +21 -0
  83. data/examples/munging/wikipedia/page_metadata/extract_page_metadata.rb.old +27 -0
  84. data/examples/munging/wikipedia/pagelinks/augment_pagelinks.pig +29 -0
  85. data/examples/munging/wikipedia/pagelinks/extract_pagelinks.rb +14 -0
  86. data/examples/munging/wikipedia/pagelinks/extract_pagelinks.rb.old +25 -0
  87. data/examples/munging/wikipedia/pagelinks/undirect_pagelinks.pig +29 -0
  88. data/examples/munging/wikipedia/pageviews/augment_pageviews.pig +32 -0
  89. data/examples/munging/wikipedia/pageviews/extract_pageviews.rb +85 -0
  90. data/examples/munging/wikipedia/pig_style_guide.md +25 -0
  91. data/examples/munging/wikipedia/redirects/redirects_page_metadata.pig +19 -0
  92. data/examples/munging/wikipedia/subuniverse/sub_articles.pig +23 -0
  93. data/examples/munging/wikipedia/subuniverse/sub_page_metadata.pig +24 -0
  94. data/examples/munging/wikipedia/subuniverse/sub_pagelinks_from.pig +22 -0
  95. data/examples/munging/wikipedia/subuniverse/sub_pagelinks_into.pig +22 -0
  96. data/examples/munging/wikipedia/subuniverse/sub_pagelinks_within.pig +26 -0
  97. data/examples/munging/wikipedia/subuniverse/sub_pageviews.pig +29 -0
  98. data/examples/munging/wikipedia/subuniverse/sub_undirected_pagelinks_within.pig +24 -0
  99. data/examples/munging/wikipedia/utils/get_namespaces.rb +86 -0
  100. data/examples/munging/wikipedia/utils/munging_utils.rb +68 -0
  101. data/examples/munging/wikipedia/utils/namespaces.json +1 -0
  102. data/examples/rake_helper.rb +85 -0
  103. data/examples/server_logs/geo_ip_mapping/munge_geolite.rb +82 -0
  104. data/examples/server_logs/logline.rb +95 -0
  105. data/examples/server_logs/models.rb +66 -0
  106. data/examples/server_logs/page_counts.pig +48 -0
  107. data/examples/server_logs/server_logs-01-parse-script.rb +13 -0
  108. data/examples/server_logs/server_logs-02-histograms-full.rb +33 -0
  109. data/examples/server_logs/server_logs-02-histograms-mapper.rb +14 -0
  110. data/{old/examples/server_logs/breadcrumbs.rb → examples/server_logs/server_logs-03-breadcrumbs-full.rb} +26 -30
  111. data/examples/server_logs/server_logs-04-page_page_edges-full.rb +40 -0
  112. data/examples/string_reverser.rb +26 -0
  113. data/examples/text/pig_latin.rb +2 -2
  114. data/examples/text/regional_flavor/README.md +14 -0
  115. data/examples/text/regional_flavor/article_wordbags.pig +39 -0
  116. data/examples/text/regional_flavor/j01-article_wordbags.rb +4 -0
  117. data/examples/text/regional_flavor/simple_pig_script.pig +27 -0
  118. data/examples/word_count/accumulator.rb +26 -0
  119. data/examples/word_count/tokenizer.rb +13 -0
  120. data/examples/word_count/word_count.rb +6 -0
  121. data/examples/workflow/cherry_pie.dot +97 -0
  122. data/examples/workflow/cherry_pie.png +0 -0
  123. data/examples/workflow/cherry_pie.rb +61 -26
  124. data/lib/hanuman.rb +34 -7
  125. data/lib/hanuman/graph.rb +55 -31
  126. data/lib/hanuman/graphvizzer.rb +199 -178
  127. data/lib/hanuman/graphvizzer/gv_models.rb +161 -0
  128. data/lib/hanuman/graphvizzer/gv_presenter.rb +97 -0
  129. data/lib/hanuman/link.rb +35 -0
  130. data/lib/hanuman/registry.rb +46 -0
  131. data/lib/hanuman/stage.rb +76 -32
  132. data/lib/wukong.rb +23 -24
  133. data/lib/wukong/boot.rb +87 -0
  134. data/lib/wukong/configuration.rb +8 -0
  135. data/lib/wukong/dataflow.rb +45 -78
  136. data/lib/wukong/driver.rb +99 -0
  137. data/lib/wukong/emitter.rb +22 -0
  138. data/lib/wukong/model/faker.rb +24 -24
  139. data/lib/wukong/model/flatpack_parser/flat.rb +60 -0
  140. data/lib/wukong/model/flatpack_parser/flatpack.rb +4 -0
  141. data/lib/wukong/model/flatpack_parser/lang.rb +46 -0
  142. data/lib/wukong/model/flatpack_parser/parser.rb +55 -0
  143. data/lib/wukong/model/flatpack_parser/tokens.rb +130 -0
  144. data/lib/wukong/processor.rb +60 -114
  145. data/lib/wukong/spec_helpers.rb +81 -0
  146. data/lib/wukong/spec_helpers/integration_driver.rb +144 -0
  147. data/lib/wukong/spec_helpers/integration_driver_matchers.rb +219 -0
  148. data/lib/wukong/spec_helpers/processor_helpers.rb +95 -0
  149. data/lib/wukong/spec_helpers/processor_methods.rb +108 -0
  150. data/lib/wukong/spec_helpers/shared_examples.rb +15 -0
  151. data/lib/wukong/spec_helpers/spec_driver.rb +28 -0
  152. data/lib/wukong/spec_helpers/spec_driver_matchers.rb +195 -0
  153. data/lib/wukong/version.rb +2 -1
  154. data/lib/wukong/widget/filters.rb +311 -0
  155. data/lib/wukong/widget/processors.rb +156 -0
  156. data/lib/wukong/widget/reducers.rb +7 -0
  157. data/lib/wukong/widget/reducers/accumulator.rb +73 -0
  158. data/lib/wukong/widget/reducers/bin.rb +318 -0
  159. data/lib/wukong/widget/reducers/count.rb +61 -0
  160. data/lib/wukong/widget/reducers/group.rb +85 -0
  161. data/lib/wukong/widget/reducers/group_concat.rb +70 -0
  162. data/lib/wukong/widget/reducers/moments.rb +72 -0
  163. data/lib/wukong/widget/reducers/sort.rb +130 -0
  164. data/lib/wukong/widget/serializers.rb +287 -0
  165. data/lib/wukong/widget/sink.rb +10 -52
  166. data/lib/wukong/widget/source.rb +7 -113
  167. data/lib/wukong/widget/utils.rb +46 -0
  168. data/lib/wukong/widgets.rb +6 -0
  169. data/spec/examples/dataflow/fibonacci_series_spec.rb +18 -0
  170. data/spec/examples/dataflow/parsing_spec.rb +12 -11
  171. data/spec/examples/dataflow/simple_spec.rb +32 -6
  172. data/spec/examples/dataflow/telegram_spec.rb +36 -36
  173. data/spec/examples/graph/minimum_spanning_tree_spec.rb +30 -31
  174. data/spec/examples/munging/airline_flights/identifiers_spec.rb +16 -0
  175. data/spec/examples/munging/airline_flights_spec.rb +202 -0
  176. data/spec/examples/text/pig_latin_spec.rb +13 -16
  177. data/spec/examples/workflow/cherry_pie_spec.rb +34 -4
  178. data/spec/hanuman/graph_spec.rb +27 -2
  179. data/spec/hanuman/hanuman_spec.rb +10 -0
  180. data/spec/hanuman/registry_spec.rb +123 -0
  181. data/spec/hanuman/stage_spec.rb +61 -7
  182. data/spec/spec_helper.rb +29 -19
  183. data/spec/support/hanuman_test_helpers.rb +14 -12
  184. data/spec/support/shared_context_for_reducers.rb +37 -0
  185. data/spec/support/shared_examples_for_builders.rb +101 -0
  186. data/spec/support/shared_examples_for_shortcuts.rb +57 -0
  187. data/spec/support/wukong_test_helpers.rb +37 -11
  188. data/spec/wukong/dataflow_spec.rb +77 -55
  189. data/spec/wukong/local_runner_spec.rb +24 -24
  190. data/spec/wukong/model/faker_spec.rb +132 -131
  191. data/spec/wukong/runner_spec.rb +8 -8
  192. data/spec/wukong/widget/filters_spec.rb +61 -0
  193. data/spec/wukong/widget/processors_spec.rb +126 -0
  194. data/spec/wukong/widget/reducers/bin_spec.rb +92 -0
  195. data/spec/wukong/widget/reducers/count_spec.rb +11 -0
  196. data/spec/wukong/widget/reducers/group_spec.rb +20 -0
  197. data/spec/wukong/widget/reducers/moments_spec.rb +36 -0
  198. data/spec/wukong/widget/reducers/sort_spec.rb +26 -0
  199. data/spec/wukong/widget/serializers_spec.rb +92 -0
  200. data/spec/wukong/widget/sink_spec.rb +15 -15
  201. data/spec/wukong/widget/source_spec.rb +65 -41
  202. data/spec/wukong/wukong_spec.rb +10 -0
  203. data/wukong.gemspec +17 -10
  204. metadata +359 -335
  205. data/.document +0 -5
  206. data/VERSION +0 -1
  207. data/bin/hdp-bin +0 -44
  208. data/bin/hdp-bzip +0 -23
  209. data/bin/hdp-cat +0 -3
  210. data/bin/hdp-catd +0 -3
  211. data/bin/hdp-cp +0 -3
  212. data/bin/hdp-du +0 -86
  213. data/bin/hdp-get +0 -3
  214. data/bin/hdp-kill +0 -3
  215. data/bin/hdp-kill-task +0 -3
  216. data/bin/hdp-ls +0 -11
  217. data/bin/hdp-mkdir +0 -2
  218. data/bin/hdp-mkdirp +0 -12
  219. data/bin/hdp-mv +0 -3
  220. data/bin/hdp-parts_to_keys.rb +0 -77
  221. data/bin/hdp-ps +0 -3
  222. data/bin/hdp-put +0 -3
  223. data/bin/hdp-rm +0 -32
  224. data/bin/hdp-sort +0 -40
  225. data/bin/hdp-stream +0 -40
  226. data/bin/hdp-stream-flat +0 -22
  227. data/bin/hdp-stream2 +0 -39
  228. data/bin/hdp-sync +0 -17
  229. data/bin/hdp-wc +0 -67
  230. data/bin/wu-flow +0 -10
  231. data/bin/wu-map +0 -17
  232. data/bin/wu-red +0 -17
  233. data/bin/wukong +0 -17
  234. data/data/CREDITS.md +0 -355
  235. data/data/graph/airfares.tsv +0 -2174
  236. data/data/text/gift_of_the_magi.txt +0 -225
  237. data/data/text/jabberwocky.txt +0 -36
  238. data/data/text/rectification_of_names.txt +0 -33
  239. data/data/twitter/a_atsigns_b.tsv +0 -64
  240. data/data/twitter/a_follows_b.tsv +0 -53
  241. data/data/twitter/tweet.tsv +0 -167
  242. data/data/twitter/twitter_user.tsv +0 -55
  243. data/data/wikipedia/dbpedia-sentences.tsv +0 -1000
  244. data/docpages/INSTALL.textile +0 -92
  245. data/docpages/LICENSE.textile +0 -107
  246. data/docpages/README-elastic_map_reduce.textile +0 -377
  247. data/docpages/README-performance.textile +0 -90
  248. data/docpages/README-wulign.textile +0 -65
  249. data/docpages/UsingWukong-part1-get_ready.textile +0 -17
  250. data/docpages/UsingWukong-part2-ThinkingBigData.textile +0 -75
  251. data/docpages/UsingWukong-part3-parsing.textile +0 -138
  252. data/docpages/_config.yml +0 -39
  253. data/docpages/avro/avro_notes.textile +0 -56
  254. data/docpages/avro/performance.textile +0 -36
  255. data/docpages/avro/tethering.textile +0 -19
  256. data/docpages/bigdata-tips.textile +0 -143
  257. data/docpages/code/api_response_example.txt +0 -20
  258. data/docpages/code/parser_skeleton.rb +0 -38
  259. data/docpages/diagrams/MapReduceDiagram.graffle +0 -0
  260. data/docpages/favicon.ico +0 -0
  261. data/docpages/gem.css +0 -16
  262. data/docpages/hadoop-tips.textile +0 -83
  263. data/docpages/index.textile +0 -92
  264. data/docpages/intro.textile +0 -8
  265. data/docpages/moreinfo.textile +0 -174
  266. data/docpages/news.html +0 -24
  267. data/docpages/pig/PigLatinExpressionsList.txt +0 -122
  268. data/docpages/pig/PigLatinReferenceManual.txt +0 -1640
  269. data/docpages/pig/commandline_params.txt +0 -26
  270. data/docpages/pig/cookbook.html +0 -481
  271. data/docpages/pig/images/hadoop-logo.jpg +0 -0
  272. data/docpages/pig/images/instruction_arrow.png +0 -0
  273. data/docpages/pig/images/pig-logo.gif +0 -0
  274. data/docpages/pig/piglatin_ref1.html +0 -1103
  275. data/docpages/pig/piglatin_ref2.html +0 -14340
  276. data/docpages/pig/setup.html +0 -505
  277. data/docpages/pig/skin/basic.css +0 -166
  278. data/docpages/pig/skin/breadcrumbs.js +0 -237
  279. data/docpages/pig/skin/fontsize.js +0 -166
  280. data/docpages/pig/skin/getBlank.js +0 -40
  281. data/docpages/pig/skin/getMenu.js +0 -45
  282. data/docpages/pig/skin/images/chapter.gif +0 -0
  283. data/docpages/pig/skin/images/chapter_open.gif +0 -0
  284. data/docpages/pig/skin/images/current.gif +0 -0
  285. data/docpages/pig/skin/images/external-link.gif +0 -0
  286. data/docpages/pig/skin/images/header_white_line.gif +0 -0
  287. data/docpages/pig/skin/images/page.gif +0 -0
  288. data/docpages/pig/skin/images/pdfdoc.gif +0 -0
  289. data/docpages/pig/skin/images/rc-b-l-15-1body-2menu-3menu.png +0 -0
  290. data/docpages/pig/skin/images/rc-b-r-15-1body-2menu-3menu.png +0 -0
  291. data/docpages/pig/skin/images/rc-b-r-5-1header-2tab-selected-3tab-selected.png +0 -0
  292. data/docpages/pig/skin/images/rc-t-l-5-1header-2searchbox-3searchbox.png +0 -0
  293. data/docpages/pig/skin/images/rc-t-l-5-1header-2tab-selected-3tab-selected.png +0 -0
  294. data/docpages/pig/skin/images/rc-t-l-5-1header-2tab-unselected-3tab-unselected.png +0 -0
  295. data/docpages/pig/skin/images/rc-t-r-15-1body-2menu-3menu.png +0 -0
  296. data/docpages/pig/skin/images/rc-t-r-5-1header-2searchbox-3searchbox.png +0 -0
  297. data/docpages/pig/skin/images/rc-t-r-5-1header-2tab-selected-3tab-selected.png +0 -0
  298. data/docpages/pig/skin/images/rc-t-r-5-1header-2tab-unselected-3tab-unselected.png +0 -0
  299. data/docpages/pig/skin/print.css +0 -54
  300. data/docpages/pig/skin/profile.css +0 -181
  301. data/docpages/pig/skin/screen.css +0 -587
  302. data/docpages/pig/tutorial.html +0 -1059
  303. data/docpages/pig/udf.html +0 -1509
  304. data/docpages/tutorial.textile +0 -283
  305. data/docpages/usage.textile +0 -195
  306. data/docpages/wutils.textile +0 -263
  307. data/examples/dataflow/complex.rb +0 -11
  308. data/examples/dataflow/donuts.rb +0 -13
  309. data/examples/tiny_count/jabberwocky_output.tsv +0 -92
  310. data/examples/word_count.rb +0 -48
  311. data/examples/workflow/fiddle.rb +0 -24
  312. data/lib/away/escapement.rb +0 -129
  313. data/lib/away/exe.rb +0 -11
  314. data/lib/away/experimental.rb +0 -5
  315. data/lib/away/from_file.rb +0 -52
  316. data/lib/away/job.rb +0 -56
  317. data/lib/away/job/rake_compat.rb +0 -17
  318. data/lib/away/registry.rb +0 -79
  319. data/lib/away/runner.rb +0 -276
  320. data/lib/away/runner/execute.rb +0 -121
  321. data/lib/away/script.rb +0 -161
  322. data/lib/away/script/hadoop_command.rb +0 -240
  323. data/lib/away/source/file_list_source.rb +0 -15
  324. data/lib/away/source/looper.rb +0 -18
  325. data/lib/away/task.rb +0 -219
  326. data/lib/hanuman/action.rb +0 -21
  327. data/lib/hanuman/chain.rb +0 -4
  328. data/lib/hanuman/graphviz.rb +0 -74
  329. data/lib/hanuman/resource.rb +0 -6
  330. data/lib/hanuman/slot.rb +0 -87
  331. data/lib/hanuman/slottable.rb +0 -220
  332. data/lib/wukong/bad_record.rb +0 -15
  333. data/lib/wukong/event.rb +0 -44
  334. data/lib/wukong/local_runner.rb +0 -55
  335. data/lib/wukong/mapred.rb +0 -3
  336. data/lib/wukong/universe.rb +0 -48
  337. data/lib/wukong/widget/filter.rb +0 -81
  338. data/lib/wukong/widget/gibberish.rb +0 -123
  339. data/lib/wukong/widget/monitor.rb +0 -26
  340. data/lib/wukong/widget/reducer.rb +0 -66
  341. data/lib/wukong/widget/stringifier.rb +0 -50
  342. data/lib/wukong/workflow.rb +0 -22
  343. data/lib/wukong/workflow/command.rb +0 -42
  344. data/old/config/emr-example.yaml +0 -48
  345. data/old/examples/README.txt +0 -17
  346. data/old/examples/contrib/jeans/README.markdown +0 -165
  347. data/old/examples/contrib/jeans/data/normalized_sizes +0 -3
  348. data/old/examples/contrib/jeans/data/orders.tsv +0 -1302
  349. data/old/examples/contrib/jeans/data/sizes +0 -3
  350. data/old/examples/contrib/jeans/normalize.rb +0 -20
  351. data/old/examples/contrib/jeans/sizes.rb +0 -55
  352. data/old/examples/corpus/bnc_word_freq.rb +0 -44
  353. data/old/examples/corpus/bucket_counter.rb +0 -47
  354. data/old/examples/corpus/dbpedia_abstract_to_sentences.rb +0 -86
  355. data/old/examples/corpus/sentence_bigrams.rb +0 -53
  356. data/old/examples/corpus/sentence_coocurrence.rb +0 -66
  357. data/old/examples/corpus/stopwords.rb +0 -138
  358. data/old/examples/corpus/words_to_bigrams.rb +0 -53
  359. data/old/examples/emr/README.textile +0 -110
  360. data/old/examples/emr/dot_wukong_dir/credentials.json +0 -7
  361. data/old/examples/emr/dot_wukong_dir/emr.yaml +0 -69
  362. data/old/examples/emr/dot_wukong_dir/emr_bootstrap.sh +0 -33
  363. data/old/examples/emr/elastic_mapreduce_example.rb +0 -28
  364. data/old/examples/network_graph/adjacency_list.rb +0 -74
  365. data/old/examples/network_graph/breadth_first_search.rb +0 -72
  366. data/old/examples/network_graph/gen_2paths.rb +0 -68
  367. data/old/examples/network_graph/gen_multi_edge.rb +0 -112
  368. data/old/examples/network_graph/gen_symmetric_links.rb +0 -64
  369. data/old/examples/pagerank/README.textile +0 -6
  370. data/old/examples/pagerank/gen_initial_pagerank_graph.pig +0 -57
  371. data/old/examples/pagerank/pagerank.rb +0 -72
  372. data/old/examples/pagerank/pagerank_initialize.rb +0 -42
  373. data/old/examples/pagerank/run_pagerank.sh +0 -21
  374. data/old/examples/sample_records.rb +0 -33
  375. data/old/examples/server_logs/apache_log_parser.rb +0 -15
  376. data/old/examples/server_logs/nook.rb +0 -48
  377. data/old/examples/server_logs/nook/faraday_dummy_adapter.rb +0 -94
  378. data/old/examples/server_logs/user_agent.rb +0 -40
  379. data/old/examples/simple_word_count.rb +0 -82
  380. data/old/examples/size.rb +0 -61
  381. data/old/examples/stats/avg_value_frequency.rb +0 -86
  382. data/old/examples/stats/binning_percentile_estimator.rb +0 -140
  383. data/old/examples/stats/data/avg_value_frequency.tsv +0 -3
  384. data/old/examples/stats/rank_and_bin.rb +0 -173
  385. data/old/examples/stupidly_simple_filter.rb +0 -40
  386. data/old/examples/word_count.rb +0 -75
  387. data/old/graph/graphviz_builder.rb +0 -580
  388. data/old/graph_easy/Attributes.pm +0 -4181
  389. data/old/graph_easy/Graphviz.pm +0 -2232
  390. data/old/wukong.rb +0 -18
  391. data/old/wukong/and_pig.rb +0 -38
  392. data/old/wukong/bad_record.rb +0 -18
  393. data/old/wukong/datatypes.rb +0 -24
  394. data/old/wukong/datatypes/enum.rb +0 -127
  395. data/old/wukong/datatypes/fake_types.rb +0 -17
  396. data/old/wukong/decorator.rb +0 -28
  397. data/old/wukong/encoding/asciize.rb +0 -108
  398. data/old/wukong/extensions.rb +0 -16
  399. data/old/wukong/extensions/array.rb +0 -18
  400. data/old/wukong/extensions/blank.rb +0 -93
  401. data/old/wukong/extensions/class.rb +0 -189
  402. data/old/wukong/extensions/date_time.rb +0 -53
  403. data/old/wukong/extensions/emittable.rb +0 -69
  404. data/old/wukong/extensions/enumerable.rb +0 -79
  405. data/old/wukong/extensions/hash.rb +0 -167
  406. data/old/wukong/extensions/hash_keys.rb +0 -16
  407. data/old/wukong/extensions/hash_like.rb +0 -150
  408. data/old/wukong/extensions/hashlike_class.rb +0 -47
  409. data/old/wukong/extensions/module.rb +0 -2
  410. data/old/wukong/extensions/pathname.rb +0 -27
  411. data/old/wukong/extensions/string.rb +0 -65
  412. data/old/wukong/extensions/struct.rb +0 -17
  413. data/old/wukong/extensions/symbol.rb +0 -11
  414. data/old/wukong/filename_pattern.rb +0 -74
  415. data/old/wukong/helper.rb +0 -7
  416. data/old/wukong/helper/stopwords.rb +0 -195
  417. data/old/wukong/helper/tokenize.rb +0 -35
  418. data/old/wukong/logger.rb +0 -38
  419. data/old/wukong/periodic_monitor.rb +0 -72
  420. data/old/wukong/schema.rb +0 -269
  421. data/old/wukong/script.rb +0 -286
  422. data/old/wukong/script/avro_command.rb +0 -5
  423. data/old/wukong/script/cassandra_loader_script.rb +0 -40
  424. data/old/wukong/script/emr_command.rb +0 -168
  425. data/old/wukong/script/hadoop_command.rb +0 -237
  426. data/old/wukong/script/local_command.rb +0 -41
  427. data/old/wukong/store.rb +0 -10
  428. data/old/wukong/store/base.rb +0 -27
  429. data/old/wukong/store/cassandra.rb +0 -10
  430. data/old/wukong/store/cassandra/streaming.rb +0 -75
  431. data/old/wukong/store/cassandra/struct_loader.rb +0 -21
  432. data/old/wukong/store/cassandra_model.rb +0 -91
  433. data/old/wukong/store/chh_chunked_flat_file_store.rb +0 -37
  434. data/old/wukong/store/chunked_flat_file_store.rb +0 -48
  435. data/old/wukong/store/conditional_store.rb +0 -57
  436. data/old/wukong/store/factory.rb +0 -8
  437. data/old/wukong/store/flat_file_store.rb +0 -89
  438. data/old/wukong/store/key_store.rb +0 -51
  439. data/old/wukong/store/null_store.rb +0 -15
  440. data/old/wukong/store/read_thru_store.rb +0 -22
  441. data/old/wukong/store/tokyo_tdb_key_store.rb +0 -33
  442. data/old/wukong/store/tyrant_rdb_key_store.rb +0 -57
  443. data/old/wukong/store/tyrant_tdb_key_store.rb +0 -20
  444. data/old/wukong/streamer.rb +0 -30
  445. data/old/wukong/streamer/accumulating_reducer.rb +0 -83
  446. data/old/wukong/streamer/base.rb +0 -126
  447. data/old/wukong/streamer/counting_reducer.rb +0 -25
  448. data/old/wukong/streamer/filter.rb +0 -20
  449. data/old/wukong/streamer/instance_streamer.rb +0 -15
  450. data/old/wukong/streamer/json_streamer.rb +0 -21
  451. data/old/wukong/streamer/line_streamer.rb +0 -12
  452. data/old/wukong/streamer/list_reducer.rb +0 -31
  453. data/old/wukong/streamer/rank_and_bin_reducer.rb +0 -145
  454. data/old/wukong/streamer/record_streamer.rb +0 -14
  455. data/old/wukong/streamer/reducer.rb +0 -11
  456. data/old/wukong/streamer/set_reducer.rb +0 -14
  457. data/old/wukong/streamer/struct_streamer.rb +0 -48
  458. data/old/wukong/streamer/summing_reducer.rb +0 -29
  459. data/old/wukong/streamer/uniq_by_last_reducer.rb +0 -51
  460. data/old/wukong/typed_struct.rb +0 -12
  461. data/spec/away/encoding_spec.rb +0 -32
  462. data/spec/away/exe_spec.rb +0 -20
  463. data/spec/away/flow_spec.rb +0 -82
  464. data/spec/away/graph_spec.rb +0 -6
  465. data/spec/away/job_spec.rb +0 -15
  466. data/spec/away/rake_compat_spec.rb +0 -9
  467. data/spec/away/script_spec.rb +0 -81
  468. data/spec/hanuman/graphviz_spec.rb +0 -29
  469. data/spec/hanuman/slot_spec.rb +0 -2
  470. data/spec/support/examples_helper.rb +0 -10
  471. data/spec/support/streamer_test_helpers.rb +0 -6
  472. data/spec/support/wukong_widget_helpers.rb +0 -66
  473. data/spec/wukong/processor_spec.rb +0 -109
  474. data/spec/wukong/widget/filter_spec.rb +0 -99
  475. data/spec/wukong/widget/stringifier_spec.rb +0 -51
  476. data/spec/wukong/workflow/command_spec.rb +0 -5
@@ -1,4181 +0,0 @@
1
- #############################################################################
2
- # Define and check attributes for a Graph::Easy textual description.
3
- #
4
- #############################################################################
5
-
6
- package Graph::Easy::Attributes;
7
-
8
- $VERSION = '0.32';
9
-
10
- package Graph::Easy;
11
-
12
- use strict;
13
- use utf8; # for examples like "Fähre"
14
-
15
- # to make it easier to remember the attribute names:
16
- my $att_aliases = {
17
- 'auto-label' => 'autolabel',
18
- 'auto-link' => 'autolink',
19
- 'auto-title' => 'autotitle',
20
- 'arrow-style' => 'arrowstyle',
21
- 'arrow-shape' => 'arrowshape',
22
- 'border-color' => 'bordercolor',
23
- 'border-style' => 'borderstyle',
24
- 'border-width' => 'borderwidth',
25
- 'font-size' => 'fontsize',
26
- 'label-color' => 'labelcolor',
27
- 'label-pos' => 'labelpos',
28
- 'text-style' => 'textstyle',
29
- 'text-wrap' => 'textwrap',
30
- 'point-style' => 'pointstyle',
31
- 'point-shape' => 'pointshape',
32
- };
33
-
34
- sub _att_aliases { $att_aliases; }
35
-
36
- #############################################################################
37
- # color handling
38
-
39
- # The W3C/SVG/CSS color scheme
40
-
41
- my $color_names = {
42
- w3c =>
43
- {
44
- inherit => 'inherit',
45
- aliceblue => '#f0f8ff',
46
- antiquewhite => '#faebd7',
47
- aquamarine => '#7fffd4',
48
- aqua => '#00ffff',
49
- azure => '#f0ffff',
50
- beige => '#f5f5dc',
51
- bisque => '#ffe4c4',
52
- black => '#000000',
53
- blanchedalmond => '#ffebcd',
54
- blue => '#0000ff',
55
- blueviolet => '#8a2be2',
56
- brown => '#a52a2a',
57
- burlywood => '#deb887',
58
- cadetblue => '#5f9ea0',
59
- chartreuse => '#7fff00',
60
- chocolate => '#d2691e',
61
- coral => '#ff7f50',
62
- cornflowerblue => '#6495ed',
63
- cornsilk => '#fff8dc',
64
- crimson => '#dc143c',
65
- cyan => '#00ffff',
66
- darkblue => '#00008b',
67
- darkcyan => '#008b8b',
68
- darkgoldenrod => '#b8860b',
69
- darkgray => '#a9a9a9',
70
- darkgreen => '#006400',
71
- darkgrey => '#a9a9a9',
72
- darkkhaki => '#bdb76b',
73
- darkmagenta => '#8b008b',
74
- darkolivegreen => '#556b2f',
75
- darkorange => '#ff8c00',
76
- darkorchid => '#9932cc',
77
- darkred => '#8b0000',
78
- darksalmon => '#e9967a',
79
- darkseagreen => '#8fbc8f',
80
- darkslateblue => '#483d8b',
81
- darkslategray => '#2f4f4f',
82
- darkslategrey => '#2f4f4f',
83
- darkturquoise => '#00ced1',
84
- darkviolet => '#9400d3',
85
- deeppink => '#ff1493',
86
- deepskyblue => '#00bfff',
87
- dimgray => '#696969',
88
- dodgerblue => '#1e90ff',
89
- firebrick => '#b22222',
90
- floralwhite => '#fffaf0',
91
- forestgreen => '#228b22',
92
- fuchsia => '#ff00ff',
93
- gainsboro => '#dcdcdc',
94
- ghostwhite => '#f8f8ff',
95
- goldenrod => '#daa520',
96
- gold => '#ffd700',
97
- gray => '#808080',
98
- green => '#008000',
99
- greenyellow => '#adff2f',
100
- grey => '#808080',
101
- honeydew => '#f0fff0',
102
- hotpink => '#ff69b4',
103
- indianred => '#cd5c5c',
104
- indigo => '#4b0082',
105
- ivory => '#fffff0',
106
- khaki => '#f0e68c',
107
- lavenderblush => '#fff0f5',
108
- lavender => '#e6e6fa',
109
- lawngreen => '#7cfc00',
110
- lemonchiffon => '#fffacd',
111
- lightblue => '#add8e6',
112
- lightcoral => '#f08080',
113
- lightcyan => '#e0ffff',
114
- lightgoldenrodyellow => '#fafad2',
115
- lightgray => '#d3d3d3',
116
- lightgreen => '#90ee90',
117
- lightgrey => '#d3d3d3',
118
- lightpink => '#ffb6c1',
119
- lightsalmon => '#ffa07a',
120
- lightseagreen => '#20b2aa',
121
- lightskyblue => '#87cefa',
122
- lightslategray => '#778899',
123
- lightslategrey => '#778899',
124
- lightsteelblue => '#b0c4de',
125
- lightyellow => '#ffffe0',
126
- limegreen => '#32cd32',
127
- lime => '#00ff00',
128
- linen => '#faf0e6',
129
- magenta => '#ff00ff',
130
- maroon => '#800000',
131
- mediumaquamarine => '#66cdaa',
132
- mediumblue => '#0000cd',
133
- mediumorchid => '#ba55d3',
134
- mediumpurple => '#9370db',
135
- mediumseagreen => '#3cb371',
136
- mediumslateblue => '#7b68ee',
137
- mediumspringgreen => '#00fa9a',
138
- mediumturquoise => '#48d1cc',
139
- mediumvioletred => '#c71585',
140
- midnightblue => '#191970',
141
- mintcream => '#f5fffa',
142
- mistyrose => '#ffe4e1',
143
- moccasin => '#ffe4b5',
144
- navajowhite => '#ffdead',
145
- navy => '#000080',
146
- oldlace => '#fdf5e6',
147
- olivedrab => '#6b8e23',
148
- olive => '#808000',
149
- orangered => '#ff4500',
150
- orange => '#ffa500',
151
- orchid => '#da70d6',
152
- palegoldenrod => '#eee8aa',
153
- palegreen => '#98fb98',
154
- paleturquoise => '#afeeee',
155
- palevioletred => '#db7093',
156
- papayawhip => '#ffefd5',
157
- peachpuff => '#ffdab9',
158
- peru => '#cd853f',
159
- pink => '#ffc0cb',
160
- plum => '#dda0dd',
161
- powderblue => '#b0e0e6',
162
- purple => '#800080',
163
- red => '#ff0000',
164
- rosybrown => '#bc8f8f',
165
- royalblue => '#4169e1',
166
- saddlebrown => '#8b4513',
167
- salmon => '#fa8072',
168
- sandybrown => '#f4a460',
169
- seagreen => '#2e8b57',
170
- seashell => '#fff5ee',
171
- sienna => '#a0522d',
172
- silver => '#c0c0c0',
173
- skyblue => '#87ceeb',
174
- slateblue => '#6a5acd',
175
- slategray => '#708090',
176
- slategrey => '#708090',
177
- snow => '#fffafa',
178
- springgreen => '#00ff7f',
179
- steelblue => '#4682b4',
180
- tan => '#d2b48c',
181
- teal => '#008080',
182
- thistle => '#d8bfd8',
183
- tomato => '#ff6347',
184
- turquoise => '#40e0d0',
185
- violet => '#ee82ee',
186
- wheat => '#f5deb3',
187
- white => '#ffffff',
188
- whitesmoke => '#f5f5f5',
189
- yellowgreen => '#9acd32',
190
- yellow => '#ffff00',
191
- },
192
-
193
- x11 => {
194
- inherit => 'inherit',
195
- aliceblue => '#f0f8ff',
196
- antiquewhite => '#faebd7',
197
- antiquewhite1 => '#ffefdb',
198
- antiquewhite2 => '#eedfcc',
199
- antiquewhite3 => '#cdc0b0',
200
- antiquewhite4 => '#8b8378',
201
- aquamarine => '#7fffd4',
202
- aquamarine1 => '#7fffd4',
203
- aquamarine2 => '#76eec6',
204
- aquamarine3 => '#66cdaa',
205
- aquamarine4 => '#458b74',
206
- azure => '#f0ffff',
207
- azure1 => '#f0ffff',
208
- azure2 => '#e0eeee',
209
- azure3 => '#c1cdcd',
210
- azure4 => '#838b8b',
211
- beige => '#f5f5dc',
212
- bisque => '#ffe4c4',
213
- bisque1 => '#ffe4c4',
214
- bisque2 => '#eed5b7',
215
- bisque3 => '#cdb79e',
216
- bisque4 => '#8b7d6b',
217
- black => '#000000',
218
- blanchedalmond => '#ffebcd',
219
- blue => '#0000ff',
220
- blue1 => '#0000ff',
221
- blue2 => '#0000ee',
222
- blue3 => '#0000cd',
223
- blue4 => '#00008b',
224
- blueviolet => '#8a2be2',
225
- brown => '#a52a2a',
226
- brown1 => '#ff4040',
227
- brown2 => '#ee3b3b',
228
- brown3 => '#cd3333',
229
- brown4 => '#8b2323',
230
- burlywood => '#deb887',
231
- burlywood1 => '#ffd39b',
232
- burlywood2 => '#eec591',
233
- burlywood3 => '#cdaa7d',
234
- burlywood4 => '#8b7355',
235
- cadetblue => '#5f9ea0',
236
- cadetblue1 => '#98f5ff',
237
- cadetblue2 => '#8ee5ee',
238
- cadetblue3 => '#7ac5cd',
239
- cadetblue4 => '#53868b',
240
- chartreuse => '#7fff00',
241
- chartreuse1 => '#7fff00',
242
- chartreuse2 => '#76ee00',
243
- chartreuse3 => '#66cd00',
244
- chartreuse4 => '#458b00',
245
- chocolate => '#d2691e',
246
- chocolate1 => '#ff7f24',
247
- chocolate2 => '#ee7621',
248
- chocolate3 => '#cd661d',
249
- chocolate4 => '#8b4513',
250
- coral => '#ff7f50',
251
- coral1 => '#ff7256',
252
- coral2 => '#ee6a50',
253
- coral3 => '#cd5b45',
254
- coral4 => '#8b3e2f',
255
- cornflowerblue => '#6495ed',
256
- cornsilk => '#fff8dc',
257
- cornsilk1 => '#fff8dc',
258
- cornsilk2 => '#eee8cd',
259
- cornsilk3 => '#cdc8b1',
260
- cornsilk4 => '#8b8878',
261
- crimson => '#dc143c',
262
- cyan => '#00ffff',
263
- cyan1 => '#00ffff',
264
- cyan2 => '#00eeee',
265
- cyan3 => '#00cdcd',
266
- cyan4 => '#008b8b',
267
- darkgoldenrod => '#b8860b',
268
- darkgoldenrod1 => '#ffb90f',
269
- darkgoldenrod2 => '#eead0e',
270
- darkgoldenrod3 => '#cd950c',
271
- darkgoldenrod4 => '#8b6508',
272
- darkgreen => '#006400',
273
- darkkhaki => '#bdb76b',
274
- darkolivegreen => '#556b2f',
275
- darkolivegreen1 => '#caff70',
276
- darkolivegreen2 => '#bcee68',
277
- darkolivegreen3 => '#a2cd5a',
278
- darkolivegreen4 => '#6e8b3d',
279
- darkorange => '#ff8c00',
280
- darkorange1 => '#ff7f00',
281
- darkorange2 => '#ee7600',
282
- darkorange3 => '#cd6600',
283
- darkorange4 => '#8b4500',
284
- darkorchid => '#9932cc',
285
- darkorchid1 => '#bf3eff',
286
- darkorchid2 => '#b23aee',
287
- darkorchid3 => '#9a32cd',
288
- darkorchid4 => '#68228b',
289
- darksalmon => '#e9967a',
290
- darkseagreen => '#8fbc8f',
291
- darkseagreen1 => '#c1ffc1',
292
- darkseagreen2 => '#b4eeb4',
293
- darkseagreen3 => '#9bcd9b',
294
- darkseagreen4 => '#698b69',
295
- darkslateblue => '#483d8b',
296
- darkslategray => '#2f4f4f',
297
- darkslategray1 => '#97ffff',
298
- darkslategray2 => '#8deeee',
299
- darkslategray3 => '#79cdcd',
300
- darkslategray4 => '#528b8b',
301
- darkslategrey => '#2f4f4f',
302
- darkturquoise => '#00ced1',
303
- darkviolet => '#9400d3',
304
- deeppink => '#ff1493',
305
- deeppink1 => '#ff1493',
306
- deeppink2 => '#ee1289',
307
- deeppink3 => '#cd1076',
308
- deeppink4 => '#8b0a50',
309
- deepskyblue => '#00bfff',
310
- deepskyblue1 => '#00bfff',
311
- deepskyblue2 => '#00b2ee',
312
- deepskyblue3 => '#009acd',
313
- deepskyblue4 => '#00688b',
314
- dimgray => '#696969',
315
- dimgrey => '#696969',
316
- dodgerblue => '#1e90ff',
317
- dodgerblue1 => '#1e90ff',
318
- dodgerblue2 => '#1c86ee',
319
- dodgerblue3 => '#1874cd',
320
- dodgerblue4 => '#104e8b',
321
- firebrick => '#b22222',
322
- firebrick1 => '#ff3030',
323
- firebrick2 => '#ee2c2c',
324
- firebrick3 => '#cd2626',
325
- firebrick4 => '#8b1a1a',
326
- floralwhite => '#fffaf0',
327
- forestgreen => '#228b22',
328
- gainsboro => '#dcdcdc',
329
- ghostwhite => '#f8f8ff',
330
- gold => '#ffd700',
331
- gold1 => '#ffd700',
332
- gold2 => '#eec900',
333
- gold3 => '#cdad00',
334
- gold4 => '#8b7500',
335
- goldenrod => '#daa520',
336
- goldenrod1 => '#ffc125',
337
- goldenrod2 => '#eeb422',
338
- goldenrod3 => '#cd9b1d',
339
- goldenrod4 => '#8b6914',
340
- gray => '#c0c0c0',
341
- gray0 => '#000000',
342
- gray1 => '#030303',
343
- gray2 => '#050505',
344
- gray3 => '#080808',
345
- gray4 => '#0a0a0a',
346
- gray5 => '#0d0d0d',
347
- gray6 => '#0f0f0f',
348
- gray7 => '#121212',
349
- gray8 => '#141414',
350
- gray9 => '#171717',
351
- gray10 => '#1a1a1a',
352
- gray11 => '#1c1c1c',
353
- gray12 => '#1f1f1f',
354
- gray13 => '#212121',
355
- gray14 => '#242424',
356
- gray15 => '#262626',
357
- gray16 => '#292929',
358
- gray17 => '#2b2b2b',
359
- gray18 => '#2e2e2e',
360
- gray19 => '#303030',
361
- gray20 => '#333333',
362
- gray21 => '#363636',
363
- gray22 => '#383838',
364
- gray23 => '#3b3b3b',
365
- gray24 => '#3d3d3d',
366
- gray25 => '#404040',
367
- gray26 => '#424242',
368
- gray27 => '#454545',
369
- gray28 => '#474747',
370
- gray29 => '#4a4a4a',
371
- gray30 => '#4d4d4d',
372
- gray31 => '#4f4f4f',
373
- gray32 => '#525252',
374
- gray33 => '#545454',
375
- gray34 => '#575757',
376
- gray35 => '#595959',
377
- gray36 => '#5c5c5c',
378
- gray37 => '#5e5e5e',
379
- gray38 => '#616161',
380
- gray39 => '#636363',
381
- gray40 => '#666666',
382
- gray41 => '#696969',
383
- gray42 => '#6b6b6b',
384
- gray43 => '#6e6e6e',
385
- gray44 => '#707070',
386
- gray45 => '#737373',
387
- gray46 => '#757575',
388
- gray47 => '#787878',
389
- gray48 => '#7a7a7a',
390
- gray49 => '#7d7d7d',
391
- gray50 => '#7f7f7f',
392
- gray51 => '#828282',
393
- gray52 => '#858585',
394
- gray53 => '#878787',
395
- gray54 => '#8a8a8a',
396
- gray55 => '#8c8c8c',
397
- gray56 => '#8f8f8f',
398
- gray57 => '#919191',
399
- gray58 => '#949494',
400
- gray59 => '#969696',
401
- gray60 => '#999999',
402
- gray61 => '#9c9c9c',
403
- gray62 => '#9e9e9e',
404
- gray63 => '#a1a1a1',
405
- gray64 => '#a3a3a3',
406
- gray65 => '#a6a6a6',
407
- gray66 => '#a8a8a8',
408
- gray67 => '#ababab',
409
- gray68 => '#adadad',
410
- gray69 => '#b0b0b0',
411
- gray70 => '#b3b3b3',
412
- gray71 => '#b5b5b5',
413
- gray72 => '#b8b8b8',
414
- gray73 => '#bababa',
415
- gray74 => '#bdbdbd',
416
- gray75 => '#bfbfbf',
417
- gray76 => '#c2c2c2',
418
- gray77 => '#c4c4c4',
419
- gray78 => '#c7c7c7',
420
- gray79 => '#c9c9c9',
421
- gray80 => '#cccccc',
422
- gray81 => '#cfcfcf',
423
- gray82 => '#d1d1d1',
424
- gray83 => '#d4d4d4',
425
- gray84 => '#d6d6d6',
426
- gray85 => '#d9d9d9',
427
- gray86 => '#dbdbdb',
428
- gray87 => '#dedede',
429
- gray88 => '#e0e0e0',
430
- gray89 => '#e3e3e3',
431
- gray90 => '#e5e5e5',
432
- gray91 => '#e8e8e8',
433
- gray92 => '#ebebeb',
434
- gray93 => '#ededed',
435
- gray94 => '#f0f0f0',
436
- gray95 => '#f2f2f2',
437
- gray96 => '#f5f5f5',
438
- gray97 => '#f7f7f7',
439
- gray98 => '#fafafa',
440
- gray99 => '#fcfcfc',
441
- gray100 => '#ffffff',
442
- green => '#00ff00',
443
- green1 => '#00ff00',
444
- green2 => '#00ee00',
445
- green3 => '#00cd00',
446
- green4 => '#008b00',
447
- greenyellow => '#adff2f',
448
- grey => '#c0c0c0',
449
- grey0 => '#000000',
450
- grey1 => '#030303',
451
- grey2 => '#050505',
452
- grey3 => '#080808',
453
- grey4 => '#0a0a0a',
454
- grey5 => '#0d0d0d',
455
- grey6 => '#0f0f0f',
456
- grey7 => '#121212',
457
- grey8 => '#141414',
458
- grey9 => '#171717',
459
- grey10 => '#1a1a1a',
460
- grey11 => '#1c1c1c',
461
- grey12 => '#1f1f1f',
462
- grey13 => '#212121',
463
- grey14 => '#242424',
464
- grey15 => '#262626',
465
- grey16 => '#292929',
466
- grey17 => '#2b2b2b',
467
- grey18 => '#2e2e2e',
468
- grey19 => '#303030',
469
- grey20 => '#333333',
470
- grey21 => '#363636',
471
- grey22 => '#383838',
472
- grey23 => '#3b3b3b',
473
- grey24 => '#3d3d3d',
474
- grey25 => '#404040',
475
- grey26 => '#424242',
476
- grey27 => '#454545',
477
- grey28 => '#474747',
478
- grey29 => '#4a4a4a',
479
- grey30 => '#4d4d4d',
480
- grey31 => '#4f4f4f',
481
- grey32 => '#525252',
482
- grey33 => '#545454',
483
- grey34 => '#575757',
484
- grey35 => '#595959',
485
- grey36 => '#5c5c5c',
486
- grey37 => '#5e5e5e',
487
- grey38 => '#616161',
488
- grey39 => '#636363',
489
- grey40 => '#666666',
490
- grey41 => '#696969',
491
- grey42 => '#6b6b6b',
492
- grey43 => '#6e6e6e',
493
- grey44 => '#707070',
494
- grey45 => '#737373',
495
- grey46 => '#757575',
496
- grey47 => '#787878',
497
- grey48 => '#7a7a7a',
498
- grey49 => '#7d7d7d',
499
- grey50 => '#7f7f7f',
500
- grey51 => '#828282',
501
- grey52 => '#858585',
502
- grey53 => '#878787',
503
- grey54 => '#8a8a8a',
504
- grey55 => '#8c8c8c',
505
- grey56 => '#8f8f8f',
506
- grey57 => '#919191',
507
- grey58 => '#949494',
508
- grey59 => '#969696',
509
- grey60 => '#999999',
510
- grey61 => '#9c9c9c',
511
- grey62 => '#9e9e9e',
512
- grey63 => '#a1a1a1',
513
- grey64 => '#a3a3a3',
514
- grey65 => '#a6a6a6',
515
- grey66 => '#a8a8a8',
516
- grey67 => '#ababab',
517
- grey68 => '#adadad',
518
- grey69 => '#b0b0b0',
519
- grey70 => '#b3b3b3',
520
- grey71 => '#b5b5b5',
521
- grey72 => '#b8b8b8',
522
- grey73 => '#bababa',
523
- grey74 => '#bdbdbd',
524
- grey75 => '#bfbfbf',
525
- grey76 => '#c2c2c2',
526
- grey77 => '#c4c4c4',
527
- grey78 => '#c7c7c7',
528
- grey79 => '#c9c9c9',
529
- grey80 => '#cccccc',
530
- grey81 => '#cfcfcf',
531
- grey82 => '#d1d1d1',
532
- grey83 => '#d4d4d4',
533
- grey84 => '#d6d6d6',
534
- grey85 => '#d9d9d9',
535
- grey86 => '#dbdbdb',
536
- grey87 => '#dedede',
537
- grey88 => '#e0e0e0',
538
- grey89 => '#e3e3e3',
539
- grey90 => '#e5e5e5',
540
- grey91 => '#e8e8e8',
541
- grey92 => '#ebebeb',
542
- grey93 => '#ededed',
543
- grey94 => '#f0f0f0',
544
- grey95 => '#f2f2f2',
545
- grey96 => '#f5f5f5',
546
- grey97 => '#f7f7f7',
547
- grey98 => '#fafafa',
548
- grey99 => '#fcfcfc',
549
- grey100 => '#ffffff',
550
- honeydew => '#f0fff0',
551
- honeydew1 => '#f0fff0',
552
- honeydew2 => '#e0eee0',
553
- honeydew3 => '#c1cdc1',
554
- honeydew4 => '#838b83',
555
- hotpink => '#ff69b4',
556
- hotpink1 => '#ff6eb4',
557
- hotpink2 => '#ee6aa7',
558
- hotpink3 => '#cd6090',
559
- hotpink4 => '#8b3a62',
560
- indianred => '#cd5c5c',
561
- indianred1 => '#ff6a6a',
562
- indianred2 => '#ee6363',
563
- indianred3 => '#cd5555',
564
- indianred4 => '#8b3a3a',
565
- indigo => '#4b0082',
566
- ivory => '#fffff0',
567
- ivory1 => '#fffff0',
568
- ivory2 => '#eeeee0',
569
- ivory3 => '#cdcdc1',
570
- ivory4 => '#8b8b83',
571
- khaki => '#f0e68c',
572
- khaki1 => '#fff68f',
573
- khaki2 => '#eee685',
574
- khaki3 => '#cdc673',
575
- khaki4 => '#8b864e',
576
- lavender => '#e6e6fa',
577
- lavenderblush => '#fff0f5',
578
- lavenderblush1 => '#fff0f5',
579
- lavenderblush2 => '#eee0e5',
580
- lavenderblush3 => '#cdc1c5',
581
- lavenderblush4 => '#8b8386',
582
- lawngreen => '#7cfc00',
583
- lemonchiffon => '#fffacd',
584
- lemonchiffon1 => '#fffacd',
585
- lemonchiffon2 => '#eee9bf',
586
- lemonchiffon3 => '#cdc9a5',
587
- lemonchiffon4 => '#8b8970',
588
- lightblue => '#add8e6',
589
- lightblue1 => '#bfefff',
590
- lightblue2 => '#b2dfee',
591
- lightblue3 => '#9ac0cd',
592
- lightblue4 => '#68838b',
593
- lightcoral => '#f08080',
594
- lightcyan => '#e0ffff',
595
- lightcyan1 => '#e0ffff',
596
- lightcyan2 => '#d1eeee',
597
- lightcyan3 => '#b4cdcd',
598
- lightcyan4 => '#7a8b8b',
599
- lightgoldenrod => '#eedd82',
600
- lightgoldenrod1 => '#ffec8b',
601
- lightgoldenrod2 => '#eedc82',
602
- lightgoldenrod3 => '#cdbe70',
603
- lightgoldenrod4 => '#8b814c',
604
- lightgoldenrodyellow => '#fafad2',
605
- lightgray => '#d3d3d3',
606
- lightgrey => '#d3d3d3',
607
- lightpink => '#ffb6c1',
608
- lightpink1 => '#ffaeb9',
609
- lightpink2 => '#eea2ad',
610
- lightpink3 => '#cd8c95',
611
- lightpink4 => '#8b5f65',
612
- lightsalmon => '#ffa07a',
613
- lightsalmon1 => '#ffa07a',
614
- lightsalmon2 => '#ee9572',
615
- lightsalmon3 => '#cd8162',
616
- lightsalmon4 => '#8b5742',
617
- lightseagreen => '#20b2aa',
618
- lightskyblue => '#87cefa',
619
- lightskyblue1 => '#b0e2ff',
620
- lightskyblue2 => '#a4d3ee',
621
- lightskyblue3 => '#8db6cd',
622
- lightskyblue4 => '#607b8b',
623
- lightslateblue => '#8470ff',
624
- lightslategray => '#778899',
625
- lightslategrey => '#778899',
626
- lightsteelblue => '#b0c4de',
627
- lightsteelblue1 => '#cae1ff',
628
- lightsteelblue2 => '#bcd2ee',
629
- lightsteelblue3 => '#a2b5cd',
630
- lightsteelblue4 => '#6e7b8b',
631
- lightyellow => '#ffffe0',
632
- lightyellow1 => '#ffffe0',
633
- lightyellow2 => '#eeeed1',
634
- lightyellow3 => '#cdcdb4',
635
- lightyellow4 => '#8b8b7a',
636
- limegreen => '#32cd32',
637
- linen => '#faf0e6',
638
- magenta => '#ff00ff',
639
- magenta1 => '#ff00ff',
640
- magenta2 => '#ee00ee',
641
- magenta3 => '#cd00cd',
642
- magenta4 => '#8b008b',
643
- maroon => '#b03060',
644
- maroon1 => '#ff34b3',
645
- maroon2 => '#ee30a7',
646
- maroon3 => '#cd2990',
647
- maroon4 => '#8b1c62',
648
- mediumaquamarine => '#66cdaa',
649
- mediumblue => '#0000cd',
650
- mediumorchid => '#ba55d3',
651
- mediumorchid1 => '#e066ff',
652
- mediumorchid2 => '#d15fee',
653
- mediumorchid3 => '#b452cd',
654
- mediumorchid4 => '#7a378b',
655
- mediumpurple => '#9370db',
656
- mediumpurple1 => '#ab82ff',
657
- mediumpurple2 => '#9f79ee',
658
- mediumpurple3 => '#8968cd',
659
- mediumpurple4 => '#5d478b',
660
- mediumseagreen => '#3cb371',
661
- mediumslateblue => '#7b68ee',
662
- mediumspringgreen => '#00fa9a',
663
- mediumturquoise => '#48d1cc',
664
- mediumvioletred => '#c71585',
665
- midnightblue => '#191970',
666
- mintcream => '#f5fffa',
667
- mistyrose => '#ffe4e1',
668
- mistyrose1 => '#ffe4e1',
669
- mistyrose2 => '#eed5d2',
670
- mistyrose3 => '#cdb7b5',
671
- mistyrose4 => '#8b7d7b',
672
- moccasin => '#ffe4b5',
673
- navajowhite => '#ffdead',
674
- navajowhite1 => '#ffdead',
675
- navajowhite2 => '#eecfa1',
676
- navajowhite3 => '#cdb38b',
677
- navajowhite4 => '#8b795e',
678
- navy => '#000080',
679
- navyblue => '#000080',
680
- oldlace => '#fdf5e6',
681
- olivedrab => '#6b8e23',
682
- olivedrab1 => '#c0ff3e',
683
- olivedrab2 => '#b3ee3a',
684
- olivedrab3 => '#9acd32',
685
- olivedrab4 => '#698b22',
686
- orange => '#ffa500',
687
- orange1 => '#ffa500',
688
- orange2 => '#ee9a00',
689
- orange3 => '#cd8500',
690
- orange4 => '#8b5a00',
691
- orangered => '#ff4500',
692
- orangered1 => '#ff4500',
693
- orangered2 => '#ee4000',
694
- orangered3 => '#cd3700',
695
- orangered4 => '#8b2500',
696
- orchid => '#da70d6',
697
- orchid1 => '#ff83fa',
698
- orchid2 => '#ee7ae9',
699
- orchid3 => '#cd69c9',
700
- orchid4 => '#8b4789',
701
- palegoldenrod => '#eee8aa',
702
- palegreen => '#98fb98',
703
- palegreen1 => '#9aff9a',
704
- palegreen2 => '#90ee90',
705
- palegreen3 => '#7ccd7c',
706
- palegreen4 => '#548b54',
707
- paleturquoise => '#afeeee',
708
- paleturquoise1 => '#bbffff',
709
- paleturquoise2 => '#aeeeee',
710
- paleturquoise3 => '#96cdcd',
711
- paleturquoise4 => '#668b8b',
712
- palevioletred => '#db7093',
713
- palevioletred1 => '#ff82ab',
714
- palevioletred2 => '#ee799f',
715
- palevioletred3 => '#cd6889',
716
- palevioletred4 => '#8b475d',
717
- papayawhip => '#ffefd5',
718
- peachpuff => '#ffdab9',
719
- peachpuff1 => '#ffdab9',
720
- peachpuff2 => '#eecbad',
721
- peachpuff3 => '#cdaf95',
722
- peachpuff4 => '#8b7765',
723
- peru => '#cd853f',
724
- pink => '#ffc0cb',
725
- pink1 => '#ffb5c5',
726
- pink2 => '#eea9b8',
727
- pink3 => '#cd919e',
728
- pink4 => '#8b636c',
729
- plum => '#dda0dd',
730
- plum1 => '#ffbbff',
731
- plum2 => '#eeaeee',
732
- plum3 => '#cd96cd',
733
- plum4 => '#8b668b',
734
- powderblue => '#b0e0e6',
735
- purple => '#a020f0',
736
- purple1 => '#9b30ff',
737
- purple2 => '#912cee',
738
- purple3 => '#7d26cd',
739
- purple4 => '#551a8b',
740
- red => '#ff0000',
741
- red1 => '#ff0000',
742
- red2 => '#ee0000',
743
- red3 => '#cd0000',
744
- red4 => '#8b0000',
745
- rosybrown => '#bc8f8f',
746
- rosybrown1 => '#ffc1c1',
747
- rosybrown2 => '#eeb4b4',
748
- rosybrown3 => '#cd9b9b',
749
- rosybrown4 => '#8b6969',
750
- royalblue => '#4169e1',
751
- royalblue1 => '#4876ff',
752
- royalblue2 => '#436eee',
753
- royalblue3 => '#3a5fcd',
754
- royalblue4 => '#27408b',
755
- saddlebrown => '#8b4513',
756
- salmon => '#fa8072',
757
- salmon1 => '#ff8c69',
758
- salmon2 => '#ee8262',
759
- salmon3 => '#cd7054',
760
- salmon4 => '#8b4c39',
761
- sandybrown => '#f4a460',
762
- seagreen => '#2e8b57',
763
- seagreen1 => '#54ff9f',
764
- seagreen2 => '#4eee94',
765
- seagreen3 => '#43cd80',
766
- seagreen4 => '#2e8b57',
767
- seashell => '#fff5ee',
768
- seashell1 => '#fff5ee',
769
- seashell2 => '#eee5de',
770
- seashell3 => '#cdc5bf',
771
- seashell4 => '#8b8682',
772
- sienna => '#a0522d',
773
- sienna1 => '#ff8247',
774
- sienna2 => '#ee7942',
775
- sienna3 => '#cd6839',
776
- sienna4 => '#8b4726',
777
- skyblue => '#87ceeb',
778
- skyblue1 => '#87ceff',
779
- skyblue2 => '#7ec0ee',
780
- skyblue3 => '#6ca6cd',
781
- skyblue4 => '#4a708b',
782
- slateblue => '#6a5acd',
783
- slateblue1 => '#836fff',
784
- slateblue2 => '#7a67ee',
785
- slateblue3 => '#6959cd',
786
- slateblue4 => '#473c8b',
787
- slategray => '#708090',
788
- slategray1 => '#c6e2ff',
789
- slategray2 => '#b9d3ee',
790
- slategray3 => '#9fb6cd',
791
- slategray4 => '#6c7b8b',
792
- slategrey => '#708090',
793
- snow => '#fffafa',
794
- snow1 => '#fffafa',
795
- snow2 => '#eee9e9',
796
- snow3 => '#cdc9c9',
797
- snow4 => '#8b8989',
798
- springgreen => '#00ff7f',
799
- springgreen1 => '#00ff7f',
800
- springgreen2 => '#00ee76',
801
- springgreen3 => '#00cd66',
802
- springgreen4 => '#008b45',
803
- steelblue => '#4682b4',
804
- steelblue1 => '#63b8ff',
805
- steelblue2 => '#5cacee',
806
- steelblue3 => '#4f94cd',
807
- steelblue4 => '#36648b',
808
- tan => '#d2b48c',
809
- tan1 => '#ffa54f',
810
- tan2 => '#ee9a49',
811
- tan3 => '#cd853f',
812
- tan4 => '#8b5a2b',
813
- thistle => '#d8bfd8',
814
- thistle1 => '#ffe1ff',
815
- thistle2 => '#eed2ee',
816
- thistle3 => '#cdb5cd',
817
- thistle4 => '#8b7b8b',
818
- tomato => '#ff6347',
819
- tomato1 => '#ff6347',
820
- tomato2 => '#ee5c42',
821
- tomato3 => '#cd4f39',
822
- tomato4 => '#8b3626',
823
- transparent => '#fffffe',
824
- turquoise => '#40e0d0',
825
- turquoise1 => '#00f5ff',
826
- turquoise2 => '#00e5ee',
827
- turquoise3 => '#00c5cd',
828
- turquoise4 => '#00868b',
829
- violet => '#ee82ee',
830
- violetred => '#d02090',
831
- violetred1 => '#ff3e96',
832
- violetred2 => '#ee3a8c',
833
- violetred3 => '#cd3278',
834
- violetred4 => '#8b2252',
835
- wheat => '#f5deb3',
836
- wheat1 => '#ffe7ba',
837
- wheat2 => '#eed8ae',
838
- wheat3 => '#cdba96',
839
- wheat4 => '#8b7e66',
840
- white => '#ffffff',
841
- whitesmoke => '#f5f5f5',
842
- yellow => '#ffff00',
843
- yellow1 => '#ffff00',
844
- yellow2 => '#eeee00',
845
- yellow3 => '#cdcd00',
846
- yellow4 => '#8b8b00',
847
- yellowgreen => '#9acd32',
848
- # The following 12 colors exist here so that a "color: 3; colorscheme: accent3"
849
- # will not report an "unknown color 3" from the Parser. As a side-effect
850
- # you will not get an error for a plain "color: 3".
851
- 1 => '#a6cee3', 2 => '#1f78b4', 3 => '#b2df8a', 4 => '#33a02c',
852
- 5 => '#fb9a99', 6 => '#e31a1c', 7 => '#fdbf6f', 8 => '#ff7f00',
853
- 9 => '#cab2d6', 10 => '#6a3d9a', 11 => '#ffff99', 12 => '#b15928',
854
- },
855
- # The following color specifications were developed by:
856
- # Cynthia Brewer (http://colorbrewer.org/)
857
- # See the LICENSE FILE for the full license that applies to them.
858
-
859
- accent3 => {
860
- 1 => '#7fc97f', 2 => '#beaed4', 3 => '#fdc086',
861
- },
862
- accent4 => {
863
- 1 => '#7fc97f', 2 => '#beaed4', 3 => '#fdc086', 4 => '#ffff99',
864
- },
865
- accent5 => {
866
- 1 => '#7fc97f', 2 => '#beaed4', 3 => '#fdc086', 4 => '#ffff99',
867
- 5 => '#386cb0',
868
- },
869
- accent6 => {
870
- 1 => '#7fc97f', 2 => '#beaed4', 3 => '#fdc086', 4 => '#ffff99',
871
- 5 => '#386cb0', 6 => '#f0027f',
872
- },
873
- accent7 => {
874
- 1 => '#7fc97f', 2 => '#beaed4', 3 => '#fdc086', 4 => '#ffff99',
875
- 5 => '#386cb0', 6 => '#f0027f', 7 => '#bf5b17',
876
- },
877
- accent8 => {
878
- 1 => '#7fc97f', 2 => '#beaed4', 3 => '#fdc086', 4 => '#ffff99',
879
- 5 => '#386cb0', 6 => '#f0027f', 7 => '#bf5b17', 8 => '#666666',
880
- },
881
- blues3 => {
882
- 1 => '#deebf7', 2 => '#9ecae1', 3 => '#3182bd',
883
- },
884
- blues4 => {
885
- 1 => '#eff3ff', 2 => '#bdd7e7', 3 => '#6baed6', 4 => '#2171b5',
886
- },
887
- blues5 => {
888
- 1 => '#eff3ff', 2 => '#bdd7e7', 3 => '#6baed6', 4 => '#3182bd',
889
- 5 => '#08519c',
890
- },
891
- blues6 => {
892
- 1 => '#eff3ff', 2 => '#c6dbef', 3 => '#9ecae1', 4 => '#6baed6',
893
- 5 => '#3182bd', 6 => '#08519c',
894
- },
895
- blues7 => {
896
- 1 => '#eff3ff', 2 => '#c6dbef', 3 => '#9ecae1', 4 => '#6baed6',
897
- 5 => '#4292c6', 6 => '#2171b5', 7 => '#084594',
898
- },
899
- blues8 => {
900
- 1 => '#f7fbff', 2 => '#deebf7', 3 => '#c6dbef', 4 => '#9ecae1',
901
- 5 => '#6baed6', 6 => '#4292c6', 7 => '#2171b5', 8 => '#084594',
902
- },
903
- blues9 => {
904
- 1 => '#f7fbff', 2 => '#deebf7', 3 => '#c6dbef', 4 => '#9ecae1',
905
- 5 => '#6baed6', 6 => '#4292c6', 7 => '#2171b5', 8 => '#08519c',
906
- 9 => '#08306b',
907
- },
908
- brbg3 => {
909
- 1 => '#d8b365', 2 => '#f5f5f5', 3 => '#5ab4ac',
910
- },
911
- brbg4 => {
912
- 1 => '#a6611a', 2 => '#dfc27d', 3 => '#80cdc1', 4 => '#018571',
913
- },
914
- brbg5 => {
915
- 1 => '#a6611a', 2 => '#dfc27d', 3 => '#f5f5f5', 4 => '#80cdc1',
916
- 5 => '#018571',
917
- },
918
- brbg6 => {
919
- 1 => '#8c510a', 2 => '#d8b365', 3 => '#f6e8c3', 4 => '#c7eae5',
920
- 5 => '#5ab4ac', 6 => '#01665e',
921
- },
922
- brbg7 => {
923
- 1 => '#8c510a', 2 => '#d8b365', 3 => '#f6e8c3', 4 => '#f5f5f5',
924
- 5 => '#c7eae5', 6 => '#5ab4ac', 7 => '#01665e',
925
- },
926
- brbg8 => {
927
- 1 => '#8c510a', 2 => '#bf812d', 3 => '#dfc27d', 4 => '#f6e8c3',
928
- 5 => '#c7eae5', 6 => '#80cdc1', 7 => '#35978f', 8 => '#01665e',
929
- },
930
- brbg9 => {
931
- 1 => '#8c510a', 2 => '#bf812d', 3 => '#dfc27d', 4 => '#f6e8c3',
932
- 5 => '#f5f5f5', 6 => '#c7eae5', 7 => '#80cdc1', 8 => '#35978f',
933
- 9 => '#01665e',
934
- },
935
- brbg10 => {
936
- 1 => '#543005', 2 => '#8c510a', 3 => '#bf812d', 4 => '#dfc27d',
937
- 5 => '#f6e8c3', 6 => '#c7eae5', 7 => '#80cdc1', 8 => '#35978f',
938
- 9 => '#01665e', 10 => '#003c30',
939
- },
940
- brbg11 => {
941
- 1 => '#543005', 2 => '#8c510a', 3 => '#bf812d', 4 => '#dfc27d',
942
- 5 => '#f6e8c3', 6 => '#f5f5f5', 7 => '#c7eae5', 8 => '#80cdc1',
943
- 9 => '#35978f', 10 => '#01665e', 11 => '#003c30',
944
- },
945
- bugn3 => {
946
- 1 => '#e5f5f9', 2 => '#99d8c9', 3 => '#2ca25f',
947
- },
948
- bugn4 => {
949
- 1 => '#edf8fb', 2 => '#b2e2e2', 3 => '#66c2a4', 4 => '#238b45',
950
- },
951
- bugn5 => {
952
- 1 => '#edf8fb', 2 => '#b2e2e2', 3 => '#66c2a4', 4 => '#2ca25f',
953
- 5 => '#006d2c',
954
- },
955
- bugn6 => {
956
- 1 => '#edf8fb', 2 => '#ccece6', 3 => '#99d8c9', 4 => '#66c2a4',
957
- 5 => '#2ca25f', 6 => '#006d2c',
958
- },
959
- bugn7 => {
960
- 1 => '#edf8fb', 2 => '#ccece6', 3 => '#99d8c9', 4 => '#66c2a4',
961
- 5 => '#41ae76', 6 => '#238b45', 7 => '#005824',
962
- },
963
- bugn8 => {
964
- 1 => '#f7fcfd', 2 => '#e5f5f9', 3 => '#ccece6', 4 => '#99d8c9',
965
- 5 => '#66c2a4', 6 => '#41ae76', 7 => '#238b45', 8 => '#005824',
966
- },
967
- bugn9 => {
968
- 1 => '#f7fcfd', 2 => '#e5f5f9', 3 => '#ccece6', 4 => '#99d8c9',
969
- 5 => '#66c2a4', 6 => '#41ae76', 7 => '#238b45', 8 => '#006d2c',
970
- 9 => '#00441b',
971
- },
972
- bupu3 => {
973
- 1 => '#e0ecf4', 2 => '#9ebcda', 3 => '#8856a7',
974
- },
975
- bupu4 => {
976
- 1 => '#edf8fb', 2 => '#b3cde3', 3 => '#8c96c6', 4 => '#88419d',
977
- },
978
- bupu5 => {
979
- 1 => '#edf8fb', 2 => '#b3cde3', 3 => '#8c96c6', 4 => '#8856a7',
980
- 5 => '#810f7c',
981
- },
982
- bupu6 => {
983
- 1 => '#edf8fb', 2 => '#bfd3e6', 3 => '#9ebcda', 4 => '#8c96c6',
984
- 5 => '#8856a7', 6 => '#810f7c',
985
- },
986
- bupu7 => {
987
- 1 => '#edf8fb', 2 => '#bfd3e6', 3 => '#9ebcda', 4 => '#8c96c6',
988
- 5 => '#8c6bb1', 6 => '#88419d', 7 => '#6e016b',
989
- },
990
- bupu8 => {
991
- 1 => '#f7fcfd', 2 => '#e0ecf4', 3 => '#bfd3e6', 4 => '#9ebcda',
992
- 5 => '#8c96c6', 6 => '#8c6bb1', 7 => '#88419d', 8 => '#6e016b',
993
- },
994
- bupu9 => {
995
- 1 => '#f7fcfd', 2 => '#e0ecf4', 3 => '#bfd3e6', 4 => '#9ebcda',
996
- 5 => '#8c96c6', 6 => '#8c6bb1', 7 => '#88419d', 8 => '#810f7c',
997
- 9 => '#4d004b',
998
- },
999
- dark23 => {
1000
- 1 => '#1b9e77', 2 => '#d95f02', 3 => '#7570b3',
1001
- },
1002
- dark24 => {
1003
- 1 => '#1b9e77', 2 => '#d95f02', 3 => '#7570b3', 4 => '#e7298a',
1004
- },
1005
- dark25 => {
1006
- 1 => '#1b9e77', 2 => '#d95f02', 3 => '#7570b3', 4 => '#e7298a',
1007
- 5 => '#66a61e',
1008
- },
1009
- dark26 => {
1010
- 1 => '#1b9e77', 2 => '#d95f02', 3 => '#7570b3', 4 => '#e7298a',
1011
- 5 => '#66a61e', 6 => '#e6ab02',
1012
- },
1013
- dark27 => {
1014
- 1 => '#1b9e77', 2 => '#d95f02', 3 => '#7570b3', 4 => '#e7298a',
1015
- 5 => '#66a61e', 6 => '#e6ab02', 7 => '#a6761d',
1016
- },
1017
- dark28 => {
1018
- 1 => '#1b9e77', 2 => '#d95f02', 3 => '#7570b3', 4 => '#e7298a',
1019
- 5 => '#66a61e', 6 => '#e6ab02', 7 => '#a6761d', 8 => '#666666',
1020
- },
1021
- gnbu3 => {
1022
- 1 => '#e0f3db', 2 => '#a8ddb5', 3 => '#43a2ca',
1023
- },
1024
- gnbu4 => {
1025
- 1 => '#f0f9e8', 2 => '#bae4bc', 3 => '#7bccc4', 4 => '#2b8cbe',
1026
- },
1027
- gnbu5 => {
1028
- 1 => '#f0f9e8', 2 => '#bae4bc', 3 => '#7bccc4', 4 => '#43a2ca',
1029
- 5 => '#0868ac',
1030
- },
1031
- gnbu6 => {
1032
- 1 => '#f0f9e8', 2 => '#ccebc5', 3 => '#a8ddb5', 4 => '#7bccc4',
1033
- 5 => '#43a2ca', 6 => '#0868ac',
1034
- },
1035
- gnbu7 => {
1036
- 1 => '#f0f9e8', 2 => '#ccebc5', 3 => '#a8ddb5', 4 => '#7bccc4',
1037
- 5 => '#4eb3d3', 6 => '#2b8cbe', 7 => '#08589e',
1038
- },
1039
- gnbu8 => {
1040
- 1 => '#f7fcf0', 2 => '#e0f3db', 3 => '#ccebc5', 4 => '#a8ddb5',
1041
- 5 => '#7bccc4', 6 => '#4eb3d3', 7 => '#2b8cbe', 8 => '#08589e',
1042
- },
1043
- gnbu9 => {
1044
- 1 => '#f7fcf0', 2 => '#e0f3db', 3 => '#ccebc5', 4 => '#a8ddb5',
1045
- 5 => '#7bccc4', 6 => '#4eb3d3', 7 => '#2b8cbe', 8 => '#0868ac',
1046
- 9 => '#084081',
1047
- },
1048
- greens3 => {
1049
- 1 => '#e5f5e0', 2 => '#a1d99b', 3 => '#31a354',
1050
- },
1051
- greens4 => {
1052
- 1 => '#edf8e9', 2 => '#bae4b3', 3 => '#74c476', 4 => '#238b45',
1053
- },
1054
- greens5 => {
1055
- 1 => '#edf8e9', 2 => '#bae4b3', 3 => '#74c476', 4 => '#31a354',
1056
- 5 => '#006d2c',
1057
- },
1058
- greens6 => {
1059
- 1 => '#edf8e9', 2 => '#c7e9c0', 3 => '#a1d99b', 4 => '#74c476',
1060
- 5 => '#31a354', 6 => '#006d2c',
1061
- },
1062
- greens7 => {
1063
- 1 => '#edf8e9', 2 => '#c7e9c0', 3 => '#a1d99b', 4 => '#74c476',
1064
- 5 => '#41ab5d', 6 => '#238b45', 7 => '#005a32',
1065
- },
1066
- greens8 => {
1067
- 1 => '#f7fcf5', 2 => '#e5f5e0', 3 => '#c7e9c0', 4 => '#a1d99b',
1068
- 5 => '#74c476', 6 => '#41ab5d', 7 => '#238b45', 8 => '#005a32',
1069
- },
1070
- greens9 => {
1071
- 1 => '#f7fcf5', 2 => '#e5f5e0', 3 => '#c7e9c0', 4 => '#a1d99b',
1072
- 5 => '#74c476', 6 => '#41ab5d', 7 => '#238b45', 8 => '#006d2c',
1073
- 9 => '#00441b',
1074
- },
1075
- greys3 => {
1076
- 1 => '#f0f0f0', 2 => '#bdbdbd', 3 => '#636363',
1077
- },
1078
- greys4 => {
1079
- 1 => '#f7f7f7', 2 => '#cccccc', 3 => '#969696', 4 => '#525252',
1080
- },
1081
- greys5 => {
1082
- 1 => '#f7f7f7', 2 => '#cccccc', 3 => '#969696', 4 => '#636363',
1083
- 5 => '#252525',
1084
- },
1085
- greys6 => {
1086
- 1 => '#f7f7f7', 2 => '#d9d9d9', 3 => '#bdbdbd', 4 => '#969696',
1087
- 5 => '#636363', 6 => '#252525',
1088
- },
1089
- greys7 => {
1090
- 1 => '#f7f7f7', 2 => '#d9d9d9', 3 => '#bdbdbd', 4 => '#969696',
1091
- 5 => '#737373', 6 => '#525252', 7 => '#252525',
1092
- },
1093
- greys8 => {
1094
- 1 => '#ffffff', 2 => '#f0f0f0', 3 => '#d9d9d9', 4 => '#bdbdbd',
1095
- 5 => '#969696', 6 => '#737373', 7 => '#525252', 8 => '#252525',
1096
- },
1097
- greys9 => {
1098
- 1 => '#ffffff', 2 => '#f0f0f0', 3 => '#d9d9d9', 4 => '#bdbdbd',
1099
- 5 => '#969696', 6 => '#737373', 7 => '#525252', 8 => '#252525',
1100
- 9 => '#000000',
1101
- },
1102
- oranges3 => {
1103
- 1 => '#fee6ce', 2 => '#fdae6b', 3 => '#e6550d',
1104
- },
1105
- oranges4 => {
1106
- 1 => '#feedde', 2 => '#fdbe85', 3 => '#fd8d3c', 4 => '#d94701',
1107
- },
1108
- oranges5 => {
1109
- 1 => '#feedde', 2 => '#fdbe85', 3 => '#fd8d3c', 4 => '#e6550d',
1110
- 5 => '#a63603',
1111
- },
1112
- oranges6 => {
1113
- 1 => '#feedde', 2 => '#fdd0a2', 3 => '#fdae6b', 4 => '#fd8d3c',
1114
- 5 => '#e6550d', 6 => '#a63603',
1115
- },
1116
- oranges7 => {
1117
- 1 => '#feedde', 2 => '#fdd0a2', 3 => '#fdae6b', 4 => '#fd8d3c',
1118
- 5 => '#f16913', 6 => '#d94801', 7 => '#8c2d04',
1119
- },
1120
- oranges8 => {
1121
- 1 => '#fff5eb', 2 => '#fee6ce', 3 => '#fdd0a2', 4 => '#fdae6b',
1122
- 5 => '#fd8d3c', 6 => '#f16913', 7 => '#d94801', 8 => '#8c2d04',
1123
- },
1124
- oranges9 => {
1125
- 1 => '#fff5eb', 2 => '#fee6ce', 3 => '#fdd0a2', 4 => '#fdae6b',
1126
- 5 => '#fd8d3c', 6 => '#f16913', 7 => '#d94801', 8 => '#a63603',
1127
- 9 => '#7f2704',
1128
- },
1129
- orrd3 => {
1130
- 1 => '#fee8c8', 2 => '#fdbb84', 3 => '#e34a33',
1131
- },
1132
- orrd4 => {
1133
- 1 => '#fef0d9', 2 => '#fdcc8a', 3 => '#fc8d59', 4 => '#d7301f',
1134
- },
1135
- orrd5 => {
1136
- 1 => '#fef0d9', 2 => '#fdcc8a', 3 => '#fc8d59', 4 => '#e34a33',
1137
- 5 => '#b30000',
1138
- },
1139
- orrd6 => {
1140
- 1 => '#fef0d9', 2 => '#fdd49e', 3 => '#fdbb84', 4 => '#fc8d59',
1141
- 5 => '#e34a33', 6 => '#b30000',
1142
- },
1143
- orrd7 => {
1144
- 1 => '#fef0d9', 2 => '#fdd49e', 3 => '#fdbb84', 4 => '#fc8d59',
1145
- 5 => '#ef6548', 6 => '#d7301f', 7 => '#990000',
1146
- },
1147
- orrd8 => {
1148
- 1 => '#fff7ec', 2 => '#fee8c8', 3 => '#fdd49e', 4 => '#fdbb84',
1149
- 5 => '#fc8d59', 6 => '#ef6548', 7 => '#d7301f', 8 => '#990000',
1150
- },
1151
- orrd9 => {
1152
- 1 => '#fff7ec', 2 => '#fee8c8', 3 => '#fdd49e', 4 => '#fdbb84',
1153
- 5 => '#fc8d59', 6 => '#ef6548', 7 => '#d7301f', 8 => '#b30000',
1154
- 9 => '#7f0000',
1155
- },
1156
- paired3 => {
1157
- 1 => '#a6cee3', 2 => '#1f78b4', 3 => '#b2df8a',
1158
- },
1159
- paired4 => {
1160
- 1 => '#a6cee3', 2 => '#1f78b4', 3 => '#b2df8a', 4 => '#33a02c',
1161
- },
1162
- paired5 => {
1163
- 1 => '#a6cee3', 2 => '#1f78b4', 3 => '#b2df8a', 4 => '#33a02c',
1164
- 5 => '#fb9a99',
1165
- },
1166
- paired6 => {
1167
- 1 => '#a6cee3', 2 => '#1f78b4', 3 => '#b2df8a', 4 => '#33a02c',
1168
- 5 => '#fb9a99', 6 => '#e31a1c',
1169
- },
1170
- paired7 => {
1171
- 1 => '#a6cee3', 2 => '#1f78b4', 3 => '#b2df8a', 4 => '#33a02c',
1172
- 5 => '#fb9a99', 6 => '#e31a1c', 7 => '#fdbf6f',
1173
- },
1174
- paired8 => {
1175
- 1 => '#a6cee3', 2 => '#1f78b4', 3 => '#b2df8a', 4 => '#33a02c',
1176
- 5 => '#fb9a99', 6 => '#e31a1c', 7 => '#fdbf6f', 8 => '#ff7f00',
1177
- },
1178
- paired9 => {
1179
- 1 => '#a6cee3', 2 => '#1f78b4', 3 => '#b2df8a', 4 => '#33a02c',
1180
- 5 => '#fb9a99', 6 => '#e31a1c', 7 => '#fdbf6f', 8 => '#ff7f00',
1181
- 9 => '#cab2d6',
1182
- },
1183
- paired10 => {
1184
- 1 => '#a6cee3', 2 => '#1f78b4', 3 => '#b2df8a', 4 => '#33a02c',
1185
- 5 => '#fb9a99', 6 => '#e31a1c', 7 => '#fdbf6f', 8 => '#ff7f00',
1186
- 9 => '#cab2d6', 10 => '#6a3d9a',
1187
- },
1188
- paired11 => {
1189
- 1 => '#a6cee3', 2 => '#1f78b4', 3 => '#b2df8a', 4 => '#33a02c',
1190
- 5 => '#fb9a99', 6 => '#e31a1c', 7 => '#fdbf6f', 8 => '#ff7f00',
1191
- 9 => '#cab2d6', 10 => '#6a3d9a', 11 => '#ffff99',
1192
- },
1193
- paired12 => {
1194
- 1 => '#a6cee3', 2 => '#1f78b4', 3 => '#b2df8a', 4 => '#33a02c',
1195
- 5 => '#fb9a99', 6 => '#e31a1c', 7 => '#fdbf6f', 8 => '#ff7f00',
1196
- 9 => '#cab2d6', 10 => '#6a3d9a', 11 => '#ffff99', 12 => '#b15928',
1197
- },
1198
- pastel13 => {
1199
- 1 => '#fbb4ae', 2 => '#b3cde3', 3 => '#ccebc5',
1200
- },
1201
- pastel14 => {
1202
- 1 => '#fbb4ae', 2 => '#b3cde3', 3 => '#ccebc5', 4 => '#decbe4',
1203
- },
1204
- pastel15 => {
1205
- 1 => '#fbb4ae', 2 => '#b3cde3', 3 => '#ccebc5', 4 => '#decbe4',
1206
- 5 => '#fed9a6',
1207
- },
1208
- pastel16 => {
1209
- 1 => '#fbb4ae', 2 => '#b3cde3', 3 => '#ccebc5', 4 => '#decbe4',
1210
- 5 => '#fed9a6', 6 => '#ffffcc',
1211
- },
1212
- pastel17 => {
1213
- 1 => '#fbb4ae', 2 => '#b3cde3', 3 => '#ccebc5', 4 => '#decbe4',
1214
- 5 => '#fed9a6', 6 => '#ffffcc', 7 => '#e5d8bd',
1215
- },
1216
- pastel18 => {
1217
- 1 => '#fbb4ae', 2 => '#b3cde3', 3 => '#ccebc5', 4 => '#decbe4',
1218
- 5 => '#fed9a6', 6 => '#ffffcc', 7 => '#e5d8bd', 8 => '#fddaec',
1219
- },
1220
- pastel19 => {
1221
- 1 => '#fbb4ae', 2 => '#b3cde3', 3 => '#ccebc5', 4 => '#decbe4',
1222
- 5 => '#fed9a6', 6 => '#ffffcc', 7 => '#e5d8bd', 8 => '#fddaec',
1223
- 9 => '#f2f2f2',
1224
- },
1225
- pastel23 => {
1226
- 1 => '#b3e2cd', 2 => '#fdcdac', 3 => '#cbd5e8',
1227
- },
1228
- pastel24 => {
1229
- 1 => '#b3e2cd', 2 => '#fdcdac', 3 => '#cbd5e8', 4 => '#f4cae4',
1230
- },
1231
- pastel25 => {
1232
- 1 => '#b3e2cd', 2 => '#fdcdac', 3 => '#cbd5e8', 4 => '#f4cae4',
1233
- 5 => '#e6f5c9',
1234
- },
1235
- pastel26 => {
1236
- 1 => '#b3e2cd', 2 => '#fdcdac', 3 => '#cbd5e8', 4 => '#f4cae4',
1237
- 5 => '#e6f5c9', 6 => '#fff2ae',
1238
- },
1239
- pastel27 => {
1240
- 1 => '#b3e2cd', 2 => '#fdcdac', 3 => '#cbd5e8', 4 => '#f4cae4',
1241
- 5 => '#e6f5c9', 6 => '#fff2ae', 7 => '#f1e2cc',
1242
- },
1243
- pastel28 => {
1244
- 1 => '#b3e2cd', 2 => '#fdcdac', 3 => '#cbd5e8', 4 => '#f4cae4',
1245
- 5 => '#e6f5c9', 6 => '#fff2ae', 7 => '#f1e2cc', 8 => '#cccccc',
1246
- },
1247
- piyg3 => {
1248
- 1 => '#e9a3c9', 2 => '#f7f7f7', 3 => '#a1d76a',
1249
- },
1250
- piyg4 => {
1251
- 1 => '#d01c8b', 2 => '#f1b6da', 3 => '#b8e186', 4 => '#4dac26',
1252
- },
1253
- piyg5 => {
1254
- 1 => '#d01c8b', 2 => '#f1b6da', 3 => '#f7f7f7', 4 => '#b8e186',
1255
- 5 => '#4dac26',
1256
- },
1257
- piyg6 => {
1258
- 1 => '#c51b7d', 2 => '#e9a3c9', 3 => '#fde0ef', 4 => '#e6f5d0',
1259
- 5 => '#a1d76a', 6 => '#4d9221',
1260
- },
1261
- piyg7 => {
1262
- 1 => '#c51b7d', 2 => '#e9a3c9', 3 => '#fde0ef', 4 => '#f7f7f7',
1263
- 5 => '#e6f5d0', 6 => '#a1d76a', 7 => '#4d9221',
1264
- },
1265
- piyg8 => {
1266
- 1 => '#c51b7d', 2 => '#de77ae', 3 => '#f1b6da', 4 => '#fde0ef',
1267
- 5 => '#e6f5d0', 6 => '#b8e186', 7 => '#7fbc41', 8 => '#4d9221',
1268
- },
1269
- piyg9 => {
1270
- 1 => '#c51b7d', 2 => '#de77ae', 3 => '#f1b6da', 4 => '#fde0ef',
1271
- 5 => '#f7f7f7', 6 => '#e6f5d0', 7 => '#b8e186', 8 => '#7fbc41',
1272
- 9 => '#4d9221',
1273
- },
1274
- piyg10 => {
1275
- 1 => '#8e0152', 2 => '#c51b7d', 3 => '#de77ae', 4 => '#f1b6da',
1276
- 5 => '#fde0ef', 6 => '#e6f5d0', 7 => '#b8e186', 8 => '#7fbc41',
1277
- 9 => '#4d9221', 10 => '#276419',
1278
- },
1279
- piyg11 => {
1280
- 1 => '#8e0152', 2 => '#c51b7d', 3 => '#de77ae', 4 => '#f1b6da',
1281
- 5 => '#fde0ef', 6 => '#f7f7f7', 7 => '#e6f5d0', 8 => '#b8e186',
1282
- 9 => '#7fbc41', 10 => '#4d9221', 11 => '#276419',
1283
- },
1284
- prgn3 => {
1285
- 1 => '#af8dc3', 2 => '#f7f7f7', 3 => '#7fbf7b',
1286
- },
1287
- prgn4 => {
1288
- 1 => '#7b3294', 2 => '#c2a5cf', 3 => '#a6dba0', 4 => '#008837',
1289
- },
1290
- prgn5 => {
1291
- 1 => '#7b3294', 2 => '#c2a5cf', 3 => '#f7f7f7', 4 => '#a6dba0',
1292
- 5 => '#008837',
1293
- },
1294
- prgn6 => {
1295
- 1 => '#762a83', 2 => '#af8dc3', 3 => '#e7d4e8', 4 => '#d9f0d3',
1296
- 5 => '#7fbf7b', 6 => '#1b7837',
1297
- },
1298
- prgn7 => {
1299
- 1 => '#762a83', 2 => '#af8dc3', 3 => '#e7d4e8', 4 => '#f7f7f7',
1300
- 5 => '#d9f0d3', 6 => '#7fbf7b', 7 => '#1b7837',
1301
- },
1302
- prgn8 => {
1303
- 1 => '#762a83', 2 => '#9970ab', 3 => '#c2a5cf', 4 => '#e7d4e8',
1304
- 5 => '#d9f0d3', 6 => '#a6dba0', 7 => '#5aae61', 8 => '#1b7837',
1305
- },
1306
- prgn9 => {
1307
- 1 => '#762a83', 2 => '#9970ab', 3 => '#c2a5cf', 4 => '#e7d4e8',
1308
- 5 => '#f7f7f7', 6 => '#d9f0d3', 7 => '#a6dba0', 8 => '#5aae61',
1309
- 9 => '#1b7837',
1310
- },
1311
- prgn10 => {
1312
- 1 => '#40004b', 2 => '#762a83', 3 => '#9970ab', 4 => '#c2a5cf',
1313
- 5 => '#e7d4e8', 6 => '#d9f0d3', 7 => '#a6dba0', 8 => '#5aae61',
1314
- 9 => '#1b7837', 10 => '#00441b',
1315
- },
1316
- prgn11 => {
1317
- 1 => '#40004b', 2 => '#762a83', 3 => '#9970ab', 4 => '#c2a5cf',
1318
- 5 => '#e7d4e8', 6 => '#f7f7f7', 7 => '#d9f0d3', 8 => '#a6dba0',
1319
- 9 => '#5aae61', 10 => '#1b7837', 11 => '#00441b',
1320
- },
1321
- pubu3 => {
1322
- 1 => '#ece7f2', 2 => '#a6bddb', 3 => '#2b8cbe',
1323
- },
1324
- pubu4 => {
1325
- 1 => '#f1eef6', 2 => '#bdc9e1', 3 => '#74a9cf', 4 => '#0570b0',
1326
- },
1327
- pubu5 => {
1328
- 1 => '#f1eef6', 2 => '#bdc9e1', 3 => '#74a9cf', 4 => '#2b8cbe',
1329
- 5 => '#045a8d',
1330
- },
1331
- pubu6 => {
1332
- 1 => '#f1eef6', 2 => '#d0d1e6', 3 => '#a6bddb', 4 => '#74a9cf',
1333
- 5 => '#2b8cbe', 6 => '#045a8d',
1334
- },
1335
- pubu7 => {
1336
- 1 => '#f1eef6', 2 => '#d0d1e6', 3 => '#a6bddb', 4 => '#74a9cf',
1337
- 5 => '#3690c0', 6 => '#0570b0', 7 => '#034e7b',
1338
- },
1339
- pubu8 => {
1340
- 1 => '#fff7fb', 2 => '#ece7f2', 3 => '#d0d1e6', 4 => '#a6bddb',
1341
- 5 => '#74a9cf', 6 => '#3690c0', 7 => '#0570b0', 8 => '#034e7b',
1342
- },
1343
- pubu9 => {
1344
- 1 => '#fff7fb', 2 => '#ece7f2', 3 => '#d0d1e6', 4 => '#a6bddb',
1345
- 5 => '#74a9cf', 6 => '#3690c0', 7 => '#0570b0', 8 => '#045a8d',
1346
- 9 => '#023858',
1347
- },
1348
- pubugn3 => {
1349
- 1 => '#ece2f0', 2 => '#a6bddb', 3 => '#1c9099',
1350
- },
1351
- pubugn4 => {
1352
- 1 => '#f6eff7', 2 => '#bdc9e1', 3 => '#67a9cf', 4 => '#02818a',
1353
- },
1354
- pubugn5 => {
1355
- 1 => '#f6eff7', 2 => '#bdc9e1', 3 => '#67a9cf', 4 => '#1c9099',
1356
- 5 => '#016c59',
1357
- },
1358
- pubugn6 => {
1359
- 1 => '#f6eff7', 2 => '#d0d1e6', 3 => '#a6bddb', 4 => '#67a9cf',
1360
- 5 => '#1c9099', 6 => '#016c59',
1361
- },
1362
- pubugn7 => {
1363
- 1 => '#f6eff7', 2 => '#d0d1e6', 3 => '#a6bddb', 4 => '#67a9cf',
1364
- 5 => '#3690c0', 6 => '#02818a', 7 => '#016450',
1365
- },
1366
- pubugn8 => {
1367
- 1 => '#fff7fb', 2 => '#ece2f0', 3 => '#d0d1e6', 4 => '#a6bddb',
1368
- 5 => '#67a9cf', 6 => '#3690c0', 7 => '#02818a', 8 => '#016450',
1369
- },
1370
- pubugn9 => {
1371
- 1 => '#fff7fb', 2 => '#ece2f0', 3 => '#d0d1e6', 4 => '#a6bddb',
1372
- 5 => '#67a9cf', 6 => '#3690c0', 7 => '#02818a', 8 => '#016c59',
1373
- 9 => '#014636',
1374
- },
1375
- puor3 => {
1376
- 1 => '#f1a340', 2 => '#f7f7f7', 3 => '#998ec3',
1377
- },
1378
- puor4 => {
1379
- 1 => '#e66101', 2 => '#fdb863', 3 => '#b2abd2', 4 => '#5e3c99',
1380
- },
1381
- puor5 => {
1382
- 1 => '#e66101', 2 => '#fdb863', 3 => '#f7f7f7', 4 => '#b2abd2',
1383
- 5 => '#5e3c99',
1384
- },
1385
- puor6 => {
1386
- 1 => '#b35806', 2 => '#f1a340', 3 => '#fee0b6', 4 => '#d8daeb',
1387
- 5 => '#998ec3', 6 => '#542788',
1388
- },
1389
- puor7 => {
1390
- 1 => '#b35806', 2 => '#f1a340', 3 => '#fee0b6', 4 => '#f7f7f7',
1391
- 5 => '#d8daeb', 6 => '#998ec3', 7 => '#542788',
1392
- },
1393
- puor8 => {
1394
- 1 => '#b35806', 2 => '#e08214', 3 => '#fdb863', 4 => '#fee0b6',
1395
- 5 => '#d8daeb', 6 => '#b2abd2', 7 => '#8073ac', 8 => '#542788',
1396
- },
1397
- puor9 => {
1398
- 1 => '#b35806', 2 => '#e08214', 3 => '#fdb863', 4 => '#fee0b6',
1399
- 5 => '#f7f7f7', 6 => '#d8daeb', 7 => '#b2abd2', 8 => '#8073ac',
1400
- 9 => '#542788',
1401
- },
1402
- purd3 => {
1403
- 1 => '#e7e1ef', 2 => '#c994c7', 3 => '#dd1c77',
1404
- },
1405
- purd4 => {
1406
- 1 => '#f1eef6', 2 => '#d7b5d8', 3 => '#df65b0', 4 => '#ce1256',
1407
- },
1408
- purd5 => {
1409
- 1 => '#f1eef6', 2 => '#d7b5d8', 3 => '#df65b0', 4 => '#dd1c77',
1410
- 5 => '#980043',
1411
- },
1412
- purd6 => {
1413
- 1 => '#f1eef6', 2 => '#d4b9da', 3 => '#c994c7', 4 => '#df65b0',
1414
- 5 => '#dd1c77', 6 => '#980043',
1415
- },
1416
- purd7 => {
1417
- 1 => '#f1eef6', 2 => '#d4b9da', 3 => '#c994c7', 4 => '#df65b0',
1418
- 5 => '#e7298a', 6 => '#ce1256', 7 => '#91003f',
1419
- },
1420
- purd8 => {
1421
- 1 => '#f7f4f9', 2 => '#e7e1ef', 3 => '#d4b9da', 4 => '#c994c7',
1422
- 5 => '#df65b0', 6 => '#e7298a', 7 => '#ce1256', 8 => '#91003f',
1423
- },
1424
- purd9 => {
1425
- 1 => '#f7f4f9', 2 => '#e7e1ef', 3 => '#d4b9da', 4 => '#c994c7',
1426
- 5 => '#df65b0', 6 => '#e7298a', 7 => '#ce1256', 8 => '#980043',
1427
- 9 => '#67001f',
1428
- },
1429
- puor10 => {
1430
- 1 => '#7f3b08', 2 => '#b35806', 3 => '#e08214', 4 => '#fdb863',
1431
- 5 => '#fee0b6', 6 => '#d8daeb', 7 => '#b2abd2', 8 => '#8073ac',
1432
- 9 => '#542788', 10 => '#2d004b',
1433
- },
1434
- puor11 => {
1435
- 1 => '#7f3b08', 2 => '#b35806', 3 => '#e08214', 4 => '#fdb863',
1436
- 5 => '#fee0b6', 6 => '#f7f7f7', 7 => '#d8daeb', 8 => '#b2abd2',
1437
- 9 => '#8073ac', 10 => '#542788', 11 => '#2d004b',
1438
- },
1439
- purples3 => {
1440
- 1 => '#efedf5', 2 => '#bcbddc', 3 => '#756bb1',
1441
- },
1442
- purples4 => {
1443
- 1 => '#f2f0f7', 2 => '#cbc9e2', 3 => '#9e9ac8', 4 => '#6a51a3',
1444
- },
1445
- purples5 => {
1446
- 1 => '#f2f0f7', 2 => '#cbc9e2', 3 => '#9e9ac8', 4 => '#756bb1',
1447
- 5 => '#54278f',
1448
- },
1449
- purples6 => {
1450
- 1 => '#f2f0f7', 2 => '#dadaeb', 3 => '#bcbddc', 4 => '#9e9ac8',
1451
- 5 => '#756bb1', 6 => '#54278f',
1452
- },
1453
- purples7 => {
1454
- 1 => '#f2f0f7', 2 => '#dadaeb', 3 => '#bcbddc', 4 => '#9e9ac8',
1455
- 5 => '#807dba', 6 => '#6a51a3', 7 => '#4a1486',
1456
- },
1457
- purples8 => {
1458
- 1 => '#fcfbfd', 2 => '#efedf5', 3 => '#dadaeb', 4 => '#bcbddc',
1459
- 5 => '#9e9ac8', 6 => '#807dba', 7 => '#6a51a3', 8 => '#4a1486',
1460
- },
1461
- purples9 => {
1462
- 1 => '#fcfbfd', 2 => '#efedf5', 3 => '#dadaeb', 4 => '#bcbddc',
1463
- 5 => '#9e9ac8', 6 => '#807dba', 7 => '#6a51a3', 8 => '#54278f',
1464
- 9 => '#3f007d',
1465
- },
1466
- rdbu10 => {
1467
- 1 => '#67001f', 2 => '#b2182b', 3 => '#d6604d', 4 => '#f4a582',
1468
- 5 => '#fddbc7', 6 => '#d1e5f0', 7 => '#92c5de', 8 => '#4393c3',
1469
- 9 => '#2166ac', 10 => '#053061',
1470
- },
1471
- rdbu11 => {
1472
- 1 => '#67001f', 2 => '#b2182b', 3 => '#d6604d', 4 => '#f4a582',
1473
- 5 => '#fddbc7', 6 => '#f7f7f7', 7 => '#d1e5f0', 8 => '#92c5de',
1474
- 9 => '#4393c3', 10 => '#2166ac', 11 => '#053061',
1475
- },
1476
- rdbu3 => {
1477
- 1 => '#ef8a62', 2 => '#f7f7f7', 3 => '#67a9cf',
1478
- },
1479
- rdbu4 => {
1480
- 1 => '#ca0020', 2 => '#f4a582', 3 => '#92c5de', 4 => '#0571b0',
1481
- },
1482
- rdbu5 => {
1483
- 1 => '#ca0020', 2 => '#f4a582', 3 => '#f7f7f7', 4 => '#92c5de',
1484
- 5 => '#0571b0',
1485
- },
1486
- rdbu6 => {
1487
- 1 => '#b2182b', 2 => '#ef8a62', 3 => '#fddbc7', 4 => '#d1e5f0',
1488
- 5 => '#67a9cf', 6 => '#2166ac',
1489
- },
1490
- rdbu7 => {
1491
- 1 => '#b2182b', 2 => '#ef8a62', 3 => '#fddbc7', 4 => '#f7f7f7',
1492
- 5 => '#d1e5f0', 6 => '#67a9cf', 7 => '#2166ac',
1493
- },
1494
- rdbu8 => {
1495
- 1 => '#b2182b', 2 => '#d6604d', 3 => '#f4a582', 4 => '#fddbc7',
1496
- 5 => '#d1e5f0', 6 => '#92c5de', 7 => '#4393c3', 8 => '#2166ac',
1497
- },
1498
- rdbu9 => {
1499
- 1 => '#b2182b', 2 => '#d6604d', 3 => '#f4a582', 4 => '#fddbc7',
1500
- 5 => '#f7f7f7', 6 => '#d1e5f0', 7 => '#92c5de', 8 => '#4393c3',
1501
- 9 => '#2166ac',
1502
- },
1503
- rdgy3 => {
1504
- 1 => '#ef8a62', 2 => '#ffffff', 3 => '#999999',
1505
- },
1506
- rdgy4 => {
1507
- 1 => '#ca0020', 2 => '#f4a582', 3 => '#bababa', 4 => '#404040',
1508
- },
1509
- rdgy5 => {
1510
- 1 => '#ca0020', 2 => '#f4a582', 3 => '#ffffff', 4 => '#bababa',
1511
- 5 => '#404040',
1512
- },
1513
- rdgy6 => {
1514
- 1 => '#b2182b', 2 => '#ef8a62', 3 => '#fddbc7', 4 => '#e0e0e0',
1515
- 5 => '#999999', 6 => '#4d4d4d',
1516
- },
1517
- rdgy7 => {
1518
- 1 => '#b2182b', 2 => '#ef8a62', 3 => '#fddbc7', 4 => '#ffffff',
1519
- 5 => '#e0e0e0', 6 => '#999999', 7 => '#4d4d4d',
1520
- },
1521
- rdgy8 => {
1522
- 1 => '#b2182b', 2 => '#d6604d', 3 => '#f4a582', 4 => '#fddbc7',
1523
- 5 => '#e0e0e0', 6 => '#bababa', 7 => '#878787', 8 => '#4d4d4d',
1524
- },
1525
- rdgy9 => {
1526
- 1 => '#b2182b', 2 => '#d6604d', 3 => '#f4a582', 4 => '#fddbc7',
1527
- 5 => '#ffffff', 6 => '#e0e0e0', 7 => '#bababa', 8 => '#878787',
1528
- 9 => '#4d4d4d',
1529
- },
1530
- rdpu3 => {
1531
- 1 => '#fde0dd', 2 => '#fa9fb5', 3 => '#c51b8a',
1532
- },
1533
- rdpu4 => {
1534
- 1 => '#feebe2', 2 => '#fbb4b9', 3 => '#f768a1', 4 => '#ae017e',
1535
- },
1536
- rdpu5 => {
1537
- 1 => '#feebe2', 2 => '#fbb4b9', 3 => '#f768a1', 4 => '#c51b8a',
1538
- 5 => '#7a0177',
1539
- },
1540
- rdpu6 => {
1541
- 1 => '#feebe2', 2 => '#fcc5c0', 3 => '#fa9fb5', 4 => '#f768a1',
1542
- 5 => '#c51b8a', 6 => '#7a0177',
1543
- },
1544
- rdpu7 => {
1545
- 1 => '#feebe2', 2 => '#fcc5c0', 3 => '#fa9fb5', 4 => '#f768a1',
1546
- 5 => '#dd3497', 6 => '#ae017e', 7 => '#7a0177',
1547
- },
1548
- rdpu8 => {
1549
- 1 => '#fff7f3', 2 => '#fde0dd', 3 => '#fcc5c0', 4 => '#fa9fb5',
1550
- 5 => '#f768a1', 6 => '#dd3497', 7 => '#ae017e', 8 => '#7a0177',
1551
- },
1552
- rdpu9 => {
1553
- 1 => '#fff7f3', 2 => '#fde0dd', 3 => '#fcc5c0', 4 => '#fa9fb5',
1554
- 5 => '#f768a1', 6 => '#dd3497', 7 => '#ae017e', 8 => '#7a0177',
1555
- 9 => '#49006a',
1556
- },
1557
- rdgy10 => {
1558
- 1 => '#67001f', 2 => '#b2182b', 3 => '#d6604d', 4 => '#f4a582',
1559
- 5 => '#fddbc7', 6 => '#e0e0e0', 7 => '#bababa', 8 => '#878787',
1560
- 9 => '#4d4d4d', 10 => '#1a1a1a',
1561
- },
1562
- rdgy11 => {
1563
- 1 => '#67001f', 2 => '#b2182b', 3 => '#d6604d', 4 => '#f4a582',
1564
- 5 => '#fddbc7', 6 => '#ffffff', 7 => '#e0e0e0', 8 => '#bababa',
1565
- 9 => '#878787', 10 => '#4d4d4d', 11 => '#1a1a1a',
1566
- },
1567
- rdylbu3 => {
1568
- 1 => '#fc8d59', 2 => '#ffffbf', 3 => '#91bfdb',
1569
- },
1570
- rdylbu4 => {
1571
- 1 => '#d7191c', 2 => '#fdae61', 3 => '#abd9e9', 4 => '#2c7bb6',
1572
- },
1573
- rdylbu5 => {
1574
- 1 => '#d7191c', 2 => '#fdae61', 3 => '#ffffbf', 4 => '#abd9e9',
1575
- 5 => '#2c7bb6',
1576
- },
1577
- rdylbu6 => {
1578
- 1 => '#d73027', 2 => '#fc8d59', 3 => '#fee090', 4 => '#e0f3f8',
1579
- 5 => '#91bfdb', 6 => '#4575b4',
1580
- },
1581
- rdylbu7 => {
1582
- 1 => '#d73027', 2 => '#fc8d59', 3 => '#fee090', 4 => '#ffffbf',
1583
- 5 => '#e0f3f8', 6 => '#91bfdb', 7 => '#4575b4',
1584
- },
1585
- rdylbu8 => {
1586
- 1 => '#d73027', 2 => '#f46d43', 3 => '#fdae61', 4 => '#fee090',
1587
- 5 => '#e0f3f8', 6 => '#abd9e9', 7 => '#74add1', 8 => '#4575b4',
1588
- },
1589
- rdylbu9 => {
1590
- 1 => '#d73027', 2 => '#f46d43', 3 => '#fdae61', 4 => '#fee090',
1591
- 5 => '#ffffbf', 6 => '#e0f3f8', 7 => '#abd9e9', 8 => '#74add1',
1592
- 9 => '#4575b4',
1593
- },
1594
- rdylbu10 => {
1595
- 1 => '#a50026', 2 => '#d73027', 3 => '#f46d43', 4 => '#fdae61',
1596
- 5 => '#fee090', 6 => '#e0f3f8', 7 => '#abd9e9', 8 => '#74add1',
1597
- 9 => '#4575b4', 10 => '#313695',
1598
- },
1599
- rdylbu11 => {
1600
- 1 => '#a50026', 2 => '#d73027', 3 => '#f46d43', 4 => '#fdae61',
1601
- 5 => '#fee090', 6 => '#ffffbf', 7 => '#e0f3f8', 8 => '#abd9e9',
1602
- 9 => '#74add1', 10 => '#4575b4', 11 => '#313695',
1603
- },
1604
- rdylgn3 => {
1605
- 1 => '#fc8d59', 2 => '#ffffbf', 3 => '#91cf60',
1606
- },
1607
- rdylgn4 => {
1608
- 1 => '#d7191c', 2 => '#fdae61', 3 => '#a6d96a', 4 => '#1a9641',
1609
- },
1610
- rdylgn5 => {
1611
- 1 => '#d7191c', 2 => '#fdae61', 3 => '#ffffbf', 4 => '#a6d96a',
1612
- 5 => '#1a9641',
1613
- },
1614
- rdylgn6 => {
1615
- 1 => '#d73027', 2 => '#fc8d59', 3 => '#fee08b', 4 => '#d9ef8b',
1616
- 5 => '#91cf60', 6 => '#1a9850',
1617
- },
1618
- rdylgn7 => {
1619
- 1 => '#d73027', 2 => '#fc8d59', 3 => '#fee08b', 4 => '#ffffbf',
1620
- 5 => '#d9ef8b', 6 => '#91cf60', 7 => '#1a9850',
1621
- },
1622
- rdylgn8 => {
1623
- 1 => '#d73027', 2 => '#f46d43', 3 => '#fdae61', 4 => '#fee08b',
1624
- 5 => '#d9ef8b', 6 => '#a6d96a', 7 => '#66bd63', 8 => '#1a9850',
1625
- },
1626
- rdylgn9 => {
1627
- 1 => '#d73027', 2 => '#f46d43', 3 => '#fdae61', 4 => '#fee08b',
1628
- 5 => '#ffffbf', 6 => '#d9ef8b', 7 => '#a6d96a', 8 => '#66bd63',
1629
- 9 => '#1a9850',
1630
- },
1631
- rdylgn10 => {
1632
- 1 => '#a50026', 2 => '#d73027', 3 => '#f46d43', 4 => '#fdae61',
1633
- 5 => '#fee08b', 6 => '#d9ef8b', 7 => '#a6d96a', 8 => '#66bd63',
1634
- 9 => '#1a9850', 10 => '#006837',
1635
- },
1636
- rdylgn11 => {
1637
- 1 => '#a50026', 2 => '#d73027', 3 => '#f46d43', 4 => '#fdae61',
1638
- 5 => '#fee08b', 6 => '#ffffbf', 7 => '#d9ef8b', 8 => '#a6d96a',
1639
- 9 => '#66bd63', 10 => '#1a9850', 11 => '#006837',
1640
- },
1641
- reds3 => {
1642
- 1 => '#fee0d2', 2 => '#fc9272', 3 => '#de2d26',
1643
- },
1644
- reds4 => {
1645
- 1 => '#fee5d9', 2 => '#fcae91', 3 => '#fb6a4a', 4 => '#cb181d',
1646
- },
1647
- reds5 => {
1648
- 1 => '#fee5d9', 2 => '#fcae91', 3 => '#fb6a4a', 4 => '#de2d26',
1649
- 5 => '#a50f15',
1650
- },
1651
- reds6 => {
1652
- 1 => '#fee5d9', 2 => '#fcbba1', 3 => '#fc9272', 4 => '#fb6a4a',
1653
- 5 => '#de2d26', 6 => '#a50f15',
1654
- },
1655
- reds7 => {
1656
- 1 => '#fee5d9', 2 => '#fcbba1', 3 => '#fc9272', 4 => '#fb6a4a',
1657
- 5 => '#ef3b2c', 6 => '#cb181d', 7 => '#99000d',
1658
- },
1659
- reds8 => {
1660
- 1 => '#fff5f0', 2 => '#fee0d2', 3 => '#fcbba1', 4 => '#fc9272',
1661
- 5 => '#fb6a4a', 6 => '#ef3b2c', 7 => '#cb181d', 8 => '#99000d',
1662
- },
1663
- reds9 => {
1664
- 1 => '#fff5f0', 2 => '#fee0d2', 3 => '#fcbba1', 4 => '#fc9272',
1665
- 5 => '#fb6a4a', 6 => '#ef3b2c', 7 => '#cb181d', 8 => '#a50f15',
1666
- 9 => '#67000d',
1667
- },
1668
- set13 => {
1669
- 1 => '#e41a1c', 2 => '#377eb8', 3 => '#4daf4a',
1670
- },
1671
- set14 => {
1672
- 1 => '#e41a1c', 2 => '#377eb8', 3 => '#4daf4a', 4 => '#984ea3',
1673
- },
1674
- set15 => {
1675
- 1 => '#e41a1c', 2 => '#377eb8', 3 => '#4daf4a', 4 => '#984ea3',
1676
- 5 => '#ff7f00',
1677
- },
1678
- set16 => {
1679
- 1 => '#e41a1c', 2 => '#377eb8', 3 => '#4daf4a', 4 => '#984ea3',
1680
- 5 => '#ff7f00', 6 => '#ffff33',
1681
- },
1682
- set17 => {
1683
- 1 => '#e41a1c', 2 => '#377eb8', 3 => '#4daf4a', 4 => '#984ea3',
1684
- 5 => '#ff7f00', 6 => '#ffff33', 7 => '#a65628',
1685
- },
1686
- set18 => {
1687
- 1 => '#e41a1c', 2 => '#377eb8', 3 => '#4daf4a', 4 => '#984ea3',
1688
- 5 => '#ff7f00', 6 => '#ffff33', 7 => '#a65628', 8 => '#f781bf',
1689
- },
1690
- set19 => {
1691
- 1 => '#e41a1c', 2 => '#377eb8', 3 => '#4daf4a', 4 => '#984ea3',
1692
- 5 => '#ff7f00', 6 => '#ffff33', 7 => '#a65628', 8 => '#f781bf',
1693
- 9 => '#999999',
1694
- },
1695
- set23 => {
1696
- 1 => '#66c2a5', 2 => '#fc8d62', 3 => '#8da0cb',
1697
- },
1698
- set24 => {
1699
- 1 => '#66c2a5', 2 => '#fc8d62', 3 => '#8da0cb', 4 => '#e78ac3',
1700
- },
1701
- set25 => {
1702
- 1 => '#66c2a5', 2 => '#fc8d62', 3 => '#8da0cb', 4 => '#e78ac3',
1703
- 5 => '#a6d854',
1704
- },
1705
- set26 => {
1706
- 1 => '#66c2a5', 2 => '#fc8d62', 3 => '#8da0cb', 4 => '#e78ac3',
1707
- 5 => '#a6d854', 6 => '#ffd92f',
1708
- },
1709
- set27 => {
1710
- 1 => '#66c2a5', 2 => '#fc8d62', 3 => '#8da0cb', 4 => '#e78ac3',
1711
- 5 => '#a6d854', 6 => '#ffd92f', 7 => '#e5c494',
1712
- },
1713
- set28 => {
1714
- 1 => '#66c2a5', 2 => '#fc8d62', 3 => '#8da0cb', 4 => '#e78ac3',
1715
- 5 => '#a6d854', 6 => '#ffd92f', 7 => '#e5c494', 8 => '#b3b3b3',
1716
- },
1717
- set33 => {
1718
- 1 => '#8dd3c7', 2 => '#ffffb3', 3 => '#bebada',
1719
- },
1720
- set34 => {
1721
- 1 => '#8dd3c7', 2 => '#ffffb3', 3 => '#bebada', 4 => '#fb8072',
1722
- },
1723
- set35 => {
1724
- 1 => '#8dd3c7', 2 => '#ffffb3', 3 => '#bebada', 4 => '#fb8072',
1725
- 5 => '#80b1d3',
1726
- },
1727
- set36 => {
1728
- 1 => '#8dd3c7', 2 => '#ffffb3', 3 => '#bebada', 4 => '#fb8072',
1729
- 5 => '#80b1d3', 6 => '#fdb462',
1730
- },
1731
- set37 => {
1732
- 1 => '#8dd3c7', 2 => '#ffffb3', 3 => '#bebada', 4 => '#fb8072',
1733
- 5 => '#80b1d3', 6 => '#fdb462', 7 => '#b3de69',
1734
- },
1735
- set38 => {
1736
- 1 => '#8dd3c7', 2 => '#ffffb3', 3 => '#bebada', 4 => '#fb8072',
1737
- 5 => '#80b1d3', 6 => '#fdb462', 7 => '#b3de69', 8 => '#fccde5',
1738
- },
1739
- set39 => {
1740
- 1 => '#8dd3c7', 2 => '#ffffb3', 3 => '#bebada', 4 => '#fb8072',
1741
- 5 => '#80b1d3', 6 => '#fdb462', 7 => '#b3de69', 8 => '#fccde5',
1742
- 9 => '#d9d9d9',
1743
- },
1744
- set310 => {
1745
- 1 => '#8dd3c7', 2 => '#ffffb3', 3 => '#bebada', 4 => '#fb8072',
1746
- 5 => '#80b1d3', 6 => '#fdb462', 7 => '#b3de69', 8 => '#fccde5',
1747
- 9 => '#d9d9d9', 10 => '#bc80bd',
1748
- },
1749
- set311 => {
1750
- 1 => '#8dd3c7', 2 => '#ffffb3', 3 => '#bebada', 4 => '#fb8072',
1751
- 5 => '#80b1d3', 6 => '#fdb462', 7 => '#b3de69', 8 => '#fccde5',
1752
- 9 => '#d9d9d9', 10 => '#bc80bd', 11 => '#ccebc5',
1753
- },
1754
- set312 => {
1755
- 1 => '#8dd3c7', 2 => '#ffffb3', 3 => '#bebada', 4 => '#fb8072',
1756
- 5 => '#80b1d3', 6 => '#fdb462', 7 => '#b3de69', 8 => '#fccde5',
1757
- 9 => '#d9d9d9', 10 => '#bc80bd', 11 => '#ccebc5', 12 => '#ffed6f',
1758
- },
1759
- spectral3 => {
1760
- 1 => '#fc8d59', 2 => '#ffffbf', 3 => '#99d594',
1761
- },
1762
- spectral4 => {
1763
- 1 => '#d7191c', 2 => '#fdae61', 3 => '#abdda4', 4 => '#2b83ba',
1764
- },
1765
- spectral5 => {
1766
- 1 => '#d7191c', 2 => '#fdae61', 3 => '#ffffbf', 4 => '#abdda4',
1767
- 5 => '#2b83ba',
1768
- },
1769
- spectral6 => {
1770
- 1 => '#d53e4f', 2 => '#fc8d59', 3 => '#fee08b', 4 => '#e6f598',
1771
- 5 => '#99d594', 6 => '#3288bd',
1772
- },
1773
- spectral7 => {
1774
- 1 => '#d53e4f', 2 => '#fc8d59', 3 => '#fee08b', 4 => '#ffffbf',
1775
- 5 => '#e6f598', 6 => '#99d594', 7 => '#3288bd',
1776
- },
1777
- spectral8 => {
1778
- 1 => '#d53e4f', 2 => '#f46d43', 3 => '#fdae61', 4 => '#fee08b',
1779
- 5 => '#e6f598', 6 => '#abdda4', 7 => '#66c2a5', 8 => '#3288bd',
1780
- },
1781
- spectral9 => {
1782
- 1 => '#d53e4f', 2 => '#f46d43', 3 => '#fdae61', 4 => '#fee08b',
1783
- 5 => '#ffffbf', 6 => '#e6f598', 7 => '#abdda4', 8 => '#66c2a5',
1784
- 9 => '#3288bd',
1785
- },
1786
- spectral10 => {
1787
- 1 => '#9e0142', 2 => '#d53e4f', 3 => '#f46d43', 4 => '#fdae61',
1788
- 5 => '#fee08b', 6 => '#e6f598', 7 => '#abdda4', 8 => '#66c2a5',
1789
- 9 => '#3288bd', 10 => '#5e4fa2',
1790
- },
1791
- spectral11 => {
1792
- 1 => '#9e0142', 2 => '#d53e4f', 3 => '#f46d43', 4 => '#fdae61',
1793
- 5 => '#fee08b', 6 => '#ffffbf', 7 => '#e6f598', 8 => '#abdda4',
1794
- 9 => '#66c2a5', 10 => '#3288bd', 11 => '#5e4fa2',
1795
- },
1796
- ylgn3 => {
1797
- 1 => '#f7fcb9', 2 => '#addd8e', 3 => '#31a354',
1798
- },
1799
- ylgn4 => {
1800
- 1 => '#ffffcc', 2 => '#c2e699', 3 => '#78c679', 4 => '#238443',
1801
- },
1802
- ylgn5 => {
1803
- 1 => '#ffffcc', 2 => '#c2e699', 3 => '#78c679', 4 => '#31a354',
1804
- 5 => '#006837',
1805
- },
1806
- ylgn6 => {
1807
- 1 => '#ffffcc', 2 => '#d9f0a3', 3 => '#addd8e', 4 => '#78c679',
1808
- 5 => '#31a354', 6 => '#006837',
1809
- },
1810
- ylgn7 => {
1811
- 1 => '#ffffcc', 2 => '#d9f0a3', 3 => '#addd8e', 4 => '#78c679',
1812
- 5 => '#41ab5d', 6 => '#238443', 7 => '#005a32',
1813
- },
1814
- ylgn8 => {
1815
- 1 => '#ffffe5', 2 => '#f7fcb9', 3 => '#d9f0a3', 4 => '#addd8e',
1816
- 5 => '#78c679', 6 => '#41ab5d', 7 => '#238443', 8 => '#005a32',
1817
- },
1818
- ylgn9 => {
1819
- 1 => '#ffffe5', 2 => '#f7fcb9', 3 => '#d9f0a3', 4 => '#addd8e',
1820
- 5 => '#78c679', 6 => '#41ab5d', 7 => '#238443', 8 => '#006837',
1821
- 9 => '#004529',
1822
- },
1823
- ylgnbu3 => {
1824
- 1 => '#edf8b1', 2 => '#7fcdbb', 3 => '#2c7fb8',
1825
- },
1826
- ylgnbu4 => {
1827
- 1 => '#ffffcc', 2 => '#a1dab4', 3 => '#41b6c4', 4 => '#225ea8',
1828
- },
1829
- ylgnbu5 => {
1830
- 1 => '#ffffcc', 2 => '#a1dab4', 3 => '#41b6c4', 4 => '#2c7fb8',
1831
- 5 => '#253494',
1832
- },
1833
- ylgnbu6 => {
1834
- 1 => '#ffffcc', 2 => '#c7e9b4', 3 => '#7fcdbb', 4 => '#41b6c4',
1835
- 5 => '#2c7fb8', 6 => '#253494',
1836
- },
1837
- ylgnbu7 => {
1838
- 1 => '#ffffcc', 2 => '#c7e9b4', 3 => '#7fcdbb', 4 => '#41b6c4',
1839
- 5 => '#1d91c0', 6 => '#225ea8', 7 => '#0c2c84',
1840
- },
1841
- ylgnbu8 => {
1842
- 1 => '#ffffd9', 2 => '#edf8b1', 3 => '#c7e9b4', 4 => '#7fcdbb',
1843
- 5 => '#41b6c4', 6 => '#1d91c0', 7 => '#225ea8', 8 => '#0c2c84',
1844
- },
1845
- ylgnbu9 => {
1846
- 1 => '#ffffd9', 2 => '#edf8b1', 3 => '#c7e9b4', 4 => '#7fcdbb',
1847
- 5 => '#41b6c4', 6 => '#1d91c0', 7 => '#225ea8', 8 => '#253494',
1848
- 9 => '#081d58',
1849
- },
1850
- ylorbr3 => {
1851
- 1 => '#fff7bc', 2 => '#fec44f', 3 => '#d95f0e',
1852
- },
1853
- ylorbr4 => {
1854
- 1 => '#ffffd4', 2 => '#fed98e', 3 => '#fe9929', 4 => '#cc4c02',
1855
- },
1856
- ylorbr5 => {
1857
- 1 => '#ffffd4', 2 => '#fed98e', 3 => '#fe9929', 4 => '#d95f0e',
1858
- 5 => '#993404',
1859
- },
1860
- ylorbr6 => {
1861
- 1 => '#ffffd4', 2 => '#fee391', 3 => '#fec44f', 4 => '#fe9929',
1862
- 5 => '#d95f0e', 6 => '#993404',
1863
- },
1864
- ylorbr7 => {
1865
- 1 => '#ffffd4', 2 => '#fee391', 3 => '#fec44f', 4 => '#fe9929',
1866
- 5 => '#ec7014', 6 => '#cc4c02', 7 => '#8c2d04',
1867
- },
1868
- ylorbr8 => {
1869
- 1 => '#ffffe5', 2 => '#fff7bc', 3 => '#fee391', 4 => '#fec44f',
1870
- 5 => '#fe9929', 6 => '#ec7014', 7 => '#cc4c02', 8 => '#8c2d04',
1871
- },
1872
- ylorbr9 => {
1873
- 1 => '#ffffe5', 2 => '#fff7bc', 3 => '#fee391', 4 => '#fec44f',
1874
- 5 => '#fe9929', 6 => '#ec7014', 7 => '#cc4c02', 8 => '#993404',
1875
- 9 => '#662506',
1876
- },
1877
- ylorrd3 => {
1878
- 1 => '#ffeda0', 2 => '#feb24c', 3 => '#f03b20',
1879
- },
1880
- ylorrd4 => {
1881
- 1 => '#ffffb2', 2 => '#fecc5c', 3 => '#fd8d3c', 4 => '#e31a1c',
1882
- },
1883
- ylorrd5 => {
1884
- 1 => '#ffffb2', 2 => '#fecc5c', 3 => '#fd8d3c', 4 => '#f03b20',
1885
- 5 => '#bd0026',
1886
- },
1887
- ylorrd6 => {
1888
- 1 => '#ffffb2', 2 => '#fed976', 3 => '#feb24c', 4 => '#fd8d3c',
1889
- 5 => '#f03b20', 6 => '#bd0026',
1890
- },
1891
- ylorrd7 => {
1892
- 1 => '#ffffb2', 2 => '#fed976', 3 => '#feb24c', 4 => '#fd8d3c',
1893
- 5 => '#fc4e2a', 6 => '#e31a1c', 7 => '#b10026',
1894
- },
1895
- ylorrd8 => {
1896
- 1 => '#ffffcc', 2 => '#ffeda0', 3 => '#fed976', 4 => '#feb24c',
1897
- 5 => '#fd8d3c', 6 => '#fc4e2a', 7 => '#e31a1c', 8 => '#b10026',
1898
- },
1899
- ylorrd9 => {
1900
- 1 => '#ffffcc', 2 => '#ffeda0', 3 => '#fed976', 4 => '#feb24c',
1901
- 5 => '#fd8d3c', 6 => '#fc4e2a', 7 => '#e31a1c', 8 => '#bd0026',
1902
- 9 => '#800026',
1903
- },
1904
- };
1905
-
1906
- # reverse mapping value => name
1907
- my $color_values = { };
1908
- my $all_color_names = { };
1909
-
1910
- {
1911
- # reverse mapping "#ff0000 => 'red'"
1912
- # also build a list of all possible color names
1913
- for my $n (keys %$color_names)
1914
- {
1915
- my $s = $color_names->{$n};
1916
- $color_values->{ $n } = {};
1917
- my $t = $color_values->{$n};
1918
- # sort the names on their length
1919
- for my $c (sort { length($a) <=> length($b) || $a cmp $b } keys %$s)
1920
- {
1921
- # don't add "blue1" if it is already set as "blue"
1922
- $t->{ $s->{$c} } = $c unless exists $t->{ $s->{$c} };
1923
- # mark as existing
1924
- $all_color_names->{ $c } = undef;
1925
- }
1926
- }
1927
- }
1928
-
1929
- our $qr_custom_attribute = qr/^x-([a-z_0-9]+-)*[a-z_0-9]+\z/;
1930
-
1931
- sub color_names
1932
- {
1933
- $color_names;
1934
- }
1935
-
1936
- sub color_name
1937
- {
1938
- # return "red" for "#ff0000"
1939
- my ($self,$color,$scheme) = @_;
1940
-
1941
- $scheme ||= 'w3c';
1942
- $color_values->{$scheme}->{$color} || $color;
1943
- }
1944
-
1945
- sub color_value
1946
- {
1947
- # return "#ff0000" for "red"
1948
- my ($self,$color,$scheme) = @_;
1949
-
1950
- $scheme ||= 'w3c';
1951
-
1952
- # 'w3c/red' => 'w3c', 'red'
1953
- $scheme = $1 if $color =~ s/^([a-z0-9])\///;
1954
-
1955
- $color_names->{$scheme}->{$color} || $color;
1956
- }
1957
-
1958
- sub _color_scheme
1959
- {
1960
- # check that a given color scheme is valid
1961
- my ($self, $scheme) = @_;
1962
-
1963
- return $scheme if $scheme eq 'inherit';
1964
- exists $color_names->{ $scheme } ? $scheme : undef;
1965
- }
1966
-
1967
- sub _color
1968
- {
1969
- # Check that a given color name (like 'red'), or value (like '#ff0000')
1970
- # or rgb(1,2,3) is valid. Used by valid_attribute().
1971
-
1972
- # Note that for color names, the color scheme is not known here, so we
1973
- # can only look if the color name is potentially possible. F.i. under
1974
- # the Brewer scheme ylorrd9, '1' is a valid color name, while 'red'
1975
- # would not. To resolve such conflicts, we will fallback to 'x11'
1976
- # (the largest of the schemes) if the color name doesn't exist in
1977
- # the current scheme.
1978
- my ($self, $org_color) = @_;
1979
-
1980
- $org_color = lc($org_color); # color names are case insensitive
1981
- $org_color =~ s/\s//g; # remove spaces to unify format
1982
- my $color = $org_color;
1983
-
1984
- if ($color =~ s/^(w3c|[a-z]+\d{0,2})\///)
1985
- {
1986
- my $scheme = $1;
1987
- return $org_color if exists $color_names->{$scheme}->{$color};
1988
- # if it didn't work, then fall back to x11
1989
- $scheme = 'x11';
1990
- return (exists $color_names->{$scheme}->{$color} ? $org_color : undef);
1991
- }
1992
-
1993
- # scheme unknown, fall back to generic handling
1994
-
1995
- # red => red
1996
- return $org_color if exists $all_color_names->{$color};
1997
-
1998
- # #ff0000 => #ff0000, rgb(1,2,3) => rgb(1,2,3)
1999
- defined $self->color_as_hex($color) ? $org_color : undef;
2000
- }
2001
-
2002
- sub _hsv_to_rgb
2003
- {
2004
- # H=0..360, S=0..1.0, V=0..1.0
2005
- my ($h, $s, $v) = @_;
2006
-
2007
- my $e = 0.0001;
2008
-
2009
- if ($s < $e)
2010
- {
2011
- $v = abs(int(256 * $v)); $v = 255 if $v > 255;
2012
- return ($v,$v,$v);
2013
- }
2014
-
2015
- my ($r,$g,$b);
2016
- $h *= 360;
2017
-
2018
- my $h1 = int($h / 60);
2019
- my $f = $h / 60 - $h1;
2020
- my $p = $v * (1 - $s);
2021
- my $q = $v * (1 - ($s * $f));
2022
- my $t = $v * (1 - ($s * (1-$f)));
2023
-
2024
- if ($h1 == 0 || $h1 == 6)
2025
- {
2026
- $r = $v; $g = $t; $b = $p;
2027
- }
2028
- elsif ($h1 == 1)
2029
- {
2030
- $r = $q; $g = $v; $b = $p;
2031
- }
2032
- elsif ($h1 == 2)
2033
- {
2034
- $r = $p; $g = $v; $b = $t;
2035
- }
2036
- elsif ($h1 == 3)
2037
- {
2038
- $r = $p; $g = $q; $b = $v;
2039
- }
2040
- elsif ($h1 == 4)
2041
- {
2042
- $r = $t; $g = $p; $b = $v;
2043
- }
2044
- else
2045
- {
2046
- $r = $v; $g = $p; $b = $q;
2047
- }
2048
- # clamp values to 0.255
2049
- $r = abs(int($r*256));
2050
- $g = abs(int($g*256));
2051
- $b = abs(int($b*256));
2052
- $r = 255 if $r > 255;
2053
- $g = 255 if $g > 255;
2054
- $b = 255 if $b > 255;
2055
-
2056
- ($r,$g,$b);
2057
- }
2058
-
2059
- sub _hsl_to_rgb
2060
- {
2061
- # H=0..360, S=0..100, L=0..100
2062
- my ($h, $s, $l) = @_;
2063
-
2064
- my $e = 0.0001;
2065
- if ($s < $e)
2066
- {
2067
- # achromatic or grey
2068
- $l = abs(int(256 * $l)); $l = 255 if $l > 255;
2069
- return ($l,$l,$l);
2070
- }
2071
-
2072
- my $t2;
2073
- if ($l < 0.5)
2074
- {
2075
- $t2 = $l * ($s + 1);
2076
- }
2077
- else
2078
- {
2079
- $t2 = $l + $s - ($l * $s);
2080
- }
2081
- my $t1 = $l * 2 - $t2;
2082
-
2083
- my ($r,$g,$b);
2084
-
2085
- # 0..359
2086
- $h %= 360 if $h >= 360;
2087
-
2088
- # $h = 0..1
2089
- $h /= 360;
2090
-
2091
- my $tr = $h + 1/3;
2092
- my $tg = $h;
2093
- my $tb = $h - 1/3;
2094
-
2095
- $tr += 1 if $tr < 0; $tr -= 1 if $tr > 1;
2096
- $tg += 1 if $tg < 0; $tg -= 1 if $tg > 1;
2097
- $tb += 1 if $tb < 0; $tb -= 1 if $tb > 1;
2098
-
2099
- my $i = 0; my @temp3 = ($tr,$tg,$tb);
2100
- my @rc;
2101
- for my $c ($r,$g,$b)
2102
- {
2103
- my $t3 = $temp3[$i++];
2104
-
2105
- if ($t3 < 1/6)
2106
- {
2107
- $c = $t1 + ($t2 - $t1) * 6 * $t3;
2108
- }
2109
- elsif ($t3 < 1/2)
2110
- {
2111
- $c = $t2;
2112
- }
2113
- elsif ($t3 < 2/3)
2114
- {
2115
- $c = $t1 + ($t2 - $t1) * 6 * (2/3 - $t3);
2116
- }
2117
- else
2118
- {
2119
- $c = $t1;
2120
- }
2121
- $c = int($c * 256); $c = 255 if $c > 255;
2122
- push @rc, $c;
2123
- }
2124
-
2125
- @rc;
2126
- }
2127
-
2128
- my $factors = {
2129
- 'rgb' => [ 255, 255, 255, 255 ],
2130
- 'hsv' => [ 1, 1, 1, 255 ],
2131
- 'hsl' => [ 360, 1, 1, 255 ],
2132
- };
2133
-
2134
- sub color_as_hex
2135
- {
2136
- # Turn "red" or rgb(255,0,0) or "#f00" into "#ff0000". Return undef for
2137
- # invalid colors.
2138
- my ($self,$color,$scheme) = @_;
2139
-
2140
- $scheme ||= 'w3c';
2141
- $color = lc($color);
2142
- # 'w3c/red' => 'w3c', 'red'
2143
- $scheme = $1 if $color =~ s/^([a-z0-9])\///;
2144
-
2145
- # convert "red" to "ffff00"
2146
- return $color_names->{$scheme}->{$color}
2147
- if exists $color_names->{$scheme}->{$color};
2148
-
2149
- # fallback to x11 scheme if color doesn't exist
2150
- return $color_names->{x11}->{$color}
2151
- if exists $color_names->{x11}->{$color};
2152
-
2153
- my $qr_num = qr/\s*
2154
- ((?:[0-9]{1,3}%?) | # 12%, 10, 2 etc
2155
- (?:[0-9]?\.[0-9]{1,5}) ) # .1, 0.1, 2.5 etc
2156
- /x;
2157
-
2158
- # rgb(255,100%,1.0) => '#ffffff'
2159
- if ($color =~ /^(rgb|hsv|hsl)\($qr_num,$qr_num,$qr_num(?:,$qr_num)?\s*\)\z/)
2160
- {
2161
- my $r = $2; my $g = $3; my $b = $4; my $a = $5; $a = 255 unless defined $a;
2162
- my $format = $1;
2163
-
2164
- my $i = 0;
2165
- for my $c ($r,$g,$b,$a)
2166
- {
2167
- # for the first value in HSL or HSV, use 360, otherwise 100. For RGB, use 255
2168
- my $factor = $factors->{$format}->[$i++];
2169
-
2170
- if ($c =~ /^([0-9]+)%\z/) # 10% => 25.5
2171
- {
2172
- $c = $1 * $factor / 100;
2173
- }
2174
- else
2175
- {
2176
- $c = $1 * $factor if $c =~ /^([0-9]+\.[0-9]+)\z/; # 0.1, 1.0
2177
- }
2178
- }
2179
-
2180
- ($r,$g,$b) = Graph::Easy::_hsv_to_rgb($r,$g,$b) if $format eq 'hsv';
2181
- ($r,$g,$b) = Graph::Easy::_hsl_to_rgb($r,$g,$b) if $format eq 'hsl';
2182
-
2183
- $a = int($a); $a = 255 if $a > 255;
2184
-
2185
- # #RRGGBB or #RRGGBBAA
2186
- $color = sprintf("#%02x%02x%02x%02x", $r,$g,$b,$a);
2187
- }
2188
-
2189
- # turn #ff0 into #ffff00
2190
- $color = "#$1$1$2$2$3$3" if $color =~ /^#([a-f0-9])([a-f0-9])([a-f[0-9])\z/;
2191
-
2192
- # #RRGGBBff => #RRGGBB (alpha value of 255 is the default)
2193
- $color =~ s/^(#......)ff\z/$1/i;
2194
-
2195
- # check final color value to be #RRGGBB or #RRGGBBAA
2196
- return undef unless $color =~ /^#([a-f0-9]{6}|[a-f0-9]{8})\z/i;
2197
-
2198
- $color;
2199
- }
2200
-
2201
- sub text_style
2202
- {
2203
- # check whether the given list of textstyle attributes is valid
2204
- my ($self, $style) = @_;
2205
-
2206
- return $style if $style =~ /^(normal|none|)\z/;
2207
-
2208
- my @styles = split /\s+/, $style;
2209
-
2210
- return undef if grep(!/^(underline|overline|line-through|italic|bold)\z/, @styles);
2211
-
2212
- $style;
2213
- }
2214
-
2215
- sub text_styles
2216
- {
2217
- # return a hash with the defined textstyles checked
2218
- my ($self) = @_;
2219
-
2220
- my $style = $self->attribute('textstyle');
2221
-
2222
- return { none => 1 } if $style =~ /^(normal|none)\z/;
2223
- return { } if $style eq '';
2224
-
2225
- my $styles = {};
2226
- for my $key ( split /\s+/, $style )
2227
- {
2228
- $styles->{$key} = 1;
2229
- }
2230
- $styles;
2231
- }
2232
-
2233
- sub text_styles_as_css
2234
- {
2235
- my ($self, $align, $fontsize) = @_;
2236
-
2237
- my $style = '';
2238
- my $ts = $self->text_styles();
2239
-
2240
- $style .= " font-style: italic;" if $ts->{italic};
2241
- $style .= " font-weight: bold;" if $ts->{bold};
2242
-
2243
- if ($ts->{underline} || $ts->{none} || $ts->{overline} || $ts->{'line-through'})
2244
- {
2245
- # XXX TODO: HTML does seem to allow only one of them
2246
- my @s;
2247
- foreach my $k (qw/underline overline line-through none/)
2248
- {
2249
- push @s, $k if $ts->{$k};
2250
- }
2251
- my $s = join(' ', @s);
2252
- $style .= " text-decoration: $s;" if $s;
2253
- }
2254
-
2255
- my $fs = $self->raw_attribute('fontsize');
2256
-
2257
- $style .= " font-size: $fs;" if $fs;
2258
-
2259
- if (!$align)
2260
- {
2261
- # XXX TODO: raw_attribute()?
2262
- my $al = $self->attribute('align');
2263
- $style .= " text-align: $al;" if $al;
2264
- }
2265
-
2266
- $style;
2267
- }
2268
-
2269
- sub _font_size_in_pixels
2270
- {
2271
- my ($self, $em, $val) = @_;
2272
-
2273
- my $fs = $val; $fs = $self->attribute('fontsize') || '' if !defined $val;
2274
- return $em if $fs eq '';
2275
-
2276
- if ($fs =~ /^([\d.]+)em\z/)
2277
- {
2278
- $fs = $1 * $em;
2279
- }
2280
- elsif ($fs =~ /^([\d.]+)%\z/)
2281
- {
2282
- $fs = ($1 / 100) * $em;
2283
- }
2284
- # this is discouraged:
2285
- elsif ($fs =~ /^([\d.]+)px\z/)
2286
- {
2287
- $fs = int($1 || 5);
2288
- }
2289
- else
2290
- {
2291
- $self->error("Illegal fontsize '$fs'");
2292
- }
2293
- $fs;
2294
- }
2295
-
2296
- # direction modifier in degrees
2297
- my $modifier = {
2298
- forward => 0, front => 0, left => -90, right => +90, back => +180,
2299
- };
2300
-
2301
- # map absolute direction to degrees
2302
- my $dirs = {
2303
- up => 0, north => 0, down => 180, south => 180, west => 270, east => 90,
2304
- 0 => 0, 180 => 180, 90 => 90, 270 => 270,
2305
- };
2306
-
2307
- # map absolute direction to side (south etc)
2308
- my $sides = {
2309
- north => 'north',
2310
- south => 'south',
2311
- east => 'east',
2312
- west => 'west',
2313
- up => 'north',
2314
- down => 'south',
2315
- 0 => 'north',
2316
- 180 => 'south',
2317
- 90 => 'east',
2318
- 270 => 'west',
2319
- };
2320
-
2321
- sub _direction_as_number
2322
- {
2323
- my ($self,$dir) = @_;
2324
-
2325
- my $d = $dirs->{$dir};
2326
- $self->_croak("$dir is not an absolut direction") unless defined $d;
2327
-
2328
- $d;
2329
- }
2330
-
2331
- sub _direction_as_side
2332
- {
2333
- my ($self,$dir) = @_;
2334
-
2335
- return unless exists $sides->{$dir};
2336
- $sides->{$dir};
2337
- }
2338
-
2339
- sub _flow_as_direction
2340
- {
2341
- # Take a flow direction (0,90,180,270 etc), and a new direction (left|south etc)
2342
- # and return the new flow. south et al will stay, while left|right etc depend
2343
- # on the incoming flow.
2344
- my ($self, $inflow, $dir) = @_;
2345
-
2346
- # in=south and dir=forward => south
2347
- # in=south and dir=back => north etc
2348
- # in=south and dir=east => east
2349
-
2350
- # return 90 unless defined $dir;
2351
-
2352
- if ($dir =~ /^(south|north|west|east|up|down|0|90|180|270)\z/)
2353
- {
2354
- # new direction is absolut, so inflow doesn't play a role
2355
- # return 0,90,180 or 270
2356
- return $dirs->{$dir};
2357
- }
2358
-
2359
- my $in = $dirs->{$inflow};
2360
- my $modifier = $modifier->{$dir};
2361
-
2362
- $self->_croak("$inflow,$dir results in undefined inflow") unless defined $in;
2363
- $self->_croak("$inflow,$dir results in undefined modifier") unless defined $modifier;
2364
-
2365
- my $out = $in + $modifier;
2366
- $out -= 360 while $out >= 360; # normalize to 0..359
2367
- $out += 360 while $out < 0; # normalize to 0..359
2368
-
2369
- $out;
2370
- }
2371
-
2372
- sub _flow_as_side
2373
- {
2374
- # Take a flow direction (0,90,180,270 etc), and a new direction (left|south etc)
2375
- # and return the new flow. south et al will stay, while left|right etc depend
2376
- # on the incoming flow.
2377
- my ($self, $inflow, $dir) = @_;
2378
-
2379
- # in=south and dir=forward => south
2380
- # in=south and dir=back => north etc
2381
- # in=south and dir=east => east
2382
-
2383
- # return 90 unless defined $dir;
2384
-
2385
- if ($dir =~ /^(south|north|west|east|up|down|0|90|180|270)\z/)
2386
- {
2387
- # new direction is absolut, so inflow doesn't play a role
2388
- # return east, west etc
2389
- return $sides->{$dir};
2390
- }
2391
-
2392
- my $in = $dirs->{$inflow};
2393
- my $modifier = $modifier->{$dir};
2394
-
2395
- $self->_croak("$inflow,$dir results in undefined inflow") unless defined $in;
2396
- $self->_croak("$inflow,$dir results in undefined modifier") unless defined $modifier;
2397
-
2398
- my $out = $in + $modifier;
2399
- $out -= 360 if $out >= 360; # normalize to 0..359
2400
-
2401
- $sides->{$out};
2402
- }
2403
-
2404
- sub _direction
2405
- {
2406
- # check that a direction (south etc) is valid
2407
- my ($self, $dir) = @_;
2408
-
2409
- $dir =~ /^(south|east|west|north|down|up|0|90|180|270|front|forward|back|left|right)\z/ ? $dir : undef;
2410
- }
2411
-
2412
- sub _border_attribute_as_html
2413
- {
2414
- # Return "solid 1px red" from the individual border(style|color|width)
2415
- # attributes, mainly for HTML output.
2416
- my ($style, $width, $color, $scheme) = @_;
2417
-
2418
- $style ||= '';
2419
- $width = '' unless defined $width;
2420
- $color = '' unless defined $color;
2421
-
2422
- $color = Graph::Easy->color_as_hex($color,$scheme)||'' if $color !~ /^#/;
2423
-
2424
- return $style if $style =~ /^(none|)\z/;
2425
-
2426
- # width: 2px for double would collapse to one line
2427
- $width = '' if $style =~ /^double/;
2428
-
2429
- # convert the style and widths to something HTML can understand
2430
-
2431
- $width = '0.5em' if $style eq 'broad';
2432
- $width = '4px' if $style =~ /^bold/;
2433
- $width = '1em' if $style eq 'wide';
2434
- $style = 'solid' if $style =~ /(broad|wide|bold)\z/;
2435
- $style = 'dashed' if $style eq 'bold-dash';
2436
- $style = 'double' if $style eq 'double-dash';
2437
-
2438
- $width = $width.'px' if $width =~ /^\s*\d+\s*\z/;
2439
-
2440
- return '' if $width eq '' && $style ne 'double';
2441
-
2442
- my $val = join(" ", $style, $width, $color);
2443
- $val =~ s/^\s+//;
2444
- $val =~ s/\s+\z//;
2445
-
2446
- $val;
2447
- }
2448
-
2449
- sub _border_attribute
2450
- {
2451
- # Return "solid 1px red" from the individual border(style|color|width)
2452
- # attributes. Used by as_txt().
2453
- my ($style, $width, $color) = @_;
2454
-
2455
- $style ||= '';
2456
- $width = '' unless defined $width;
2457
- $color = '' unless defined $color;
2458
-
2459
- return $style if $style =~ /^(none|)\z/;
2460
-
2461
- $width = $width.'px' if $width =~ /^\s*\d+\s*\z/;
2462
-
2463
- my $val = join(" ", $style, $width, $color);
2464
- $val =~ s/^\s+//;
2465
- $val =~ s/\s+\z//;
2466
-
2467
- $val;
2468
- }
2469
-
2470
- sub _border_width_in_pixels
2471
- {
2472
- my ($self, $em) = @_;
2473
-
2474
- my $bw = $self->attribute('borderwidth') || '0';
2475
- return 0 if $bw eq '0';
2476
-
2477
- my $bs = $self->attribute('borderstyle') || 'none';
2478
-
2479
- return 0 if $bs eq 'none';
2480
- return 3 if $bs =~ /^bold/;
2481
- return $em / 2 if $bs =~ /^broad/;
2482
- return $em if $bs =~ /^wide/;
2483
-
2484
- # width: 1 is 1px;
2485
- return $bw if $bw =~ /^([\d.]+)\z/;
2486
-
2487
- if ($bw =~ /^([\d.]+)em\z/)
2488
- {
2489
- $bw = $1 * $em;
2490
- }
2491
- elsif ($bw =~ /^([\d.]+)%\z/)
2492
- {
2493
- $bw = ($1 / 100) * $em;
2494
- }
2495
- # this is discouraged:
2496
- elsif ($bw =~ /^([\d.]+)px\z/)
2497
- {
2498
- $bw = $1;
2499
- }
2500
- else
2501
- {
2502
- $self->error("Illegal borderwidth '$bw'");
2503
- }
2504
- $bw;
2505
- }
2506
-
2507
- sub _angle
2508
- {
2509
- # check an angle for being valid
2510
- my ($self, $angle) = @_;
2511
-
2512
- return undef unless $angle =~ /^([+-]?\d{1,3}|south|west|east|north|up|down|left|right|front|back|forward)\z/;
2513
-
2514
- $angle;
2515
- }
2516
-
2517
- sub _uint
2518
- {
2519
- # check a small unsigned integer for being valid
2520
- my ($self, $val) = @_;
2521
-
2522
- return undef unless $val =~ /^\d+\z/;
2523
-
2524
- $val = abs(int($val));
2525
- $val = 4 * 1024 if $val > 4 * 1024;
2526
-
2527
- $val;
2528
- }
2529
-
2530
- sub _font
2531
- {
2532
- # check a font-list for being valid
2533
- my ($self, $font) = @_;
2534
-
2535
- $font;
2536
- }
2537
-
2538
- sub split_border_attributes
2539
- {
2540
- # split "1px solid black" or "red dotted" into style, width and color
2541
- my ($self,$border) = @_;
2542
-
2543
- # special case
2544
- return ('none', undef, undef) if $border eq '0';
2545
-
2546
- # extract style
2547
- my $style;
2548
- $border =~
2549
- s/(solid|dotted|dot-dot-dash|dot-dash|dashed|double-dash|double|bold-dash|bold|broad|wide|wave|none)/$style=$1;''/eg;
2550
-
2551
- $style ||= 'solid';
2552
-
2553
- # extract width
2554
- $border =~ s/(\d+(px|em|%))//g;
2555
-
2556
- my $width = $1 || '';
2557
- $width =~ s/[^0-9]+//g; # leave only digits
2558
-
2559
- $border =~ s/\s+//g; # rem unnec. spaces
2560
-
2561
- # The left-over part must be a valid color.
2562
- my $color = $border;
2563
- $color = Graph::Easy->_color($border) if $border ne '';
2564
-
2565
- $self->error("$border is not a valid bordercolor")
2566
- unless defined $color;
2567
-
2568
- $width = undef if $width eq '';
2569
- $color = undef if $color eq '';
2570
- $style = undef if $style eq '';
2571
- ($style,$width,$color);
2572
- }
2573
-
2574
- #############################################################################
2575
- # attribute checking
2576
-
2577
- # different types of attributes with pre-defined handling
2578
- use constant {
2579
- ATTR_STRING => 0, # an arbitrary string
2580
- ATTR_COLOR => 1, # color name or value like rgb(1,1,1)
2581
- ATTR_ANGLE => 2, # 0 .. 359.99
2582
- ATTR_PORT => 3, # east, etc.
2583
- ATTR_UINT => 4, # a "small" unsigned integer
2584
- ATTR_URL => 5,
2585
-
2586
- # these cannot have "inherit", see ATTR_INHERIT_MIN
2587
- ATTR_LIST => 6, # a list of values
2588
- ATTR_LCTEXT => 7, # lowercase text (classname)
2589
- ATTR_TEXT => 8, # titles, links, labels etc
2590
-
2591
- ATTR_NO_INHERIT => 6,
2592
-
2593
- ATTR_DESC_SLOT => 0,
2594
- ATTR_MATCH_SLOT => 1,
2595
- ATTR_DEFAULT_SLOT => 2,
2596
- ATTR_EXAMPLE_SLOT => 3,
2597
- ATTR_TYPE_SLOT => 4,
2598
-
2599
-
2600
- };
2601
-
2602
- # Lists the attribute names along with
2603
- # * a short description,
2604
- # * regexp or sub name to match valid attributes
2605
- # * default value
2606
- # * an short example value
2607
- # * type
2608
- # * graph examples
2609
-
2610
- my $attributes = {
2611
- all => {
2612
- align => [
2613
- "The alignment of the label text.",
2614
- [ qw/center left right/ ],
2615
- { default => 'center', group => 'left', edge => 'left' },
2616
- 'right',
2617
- undef,
2618
- "graph { align: left; label: My Graph; }\nnode {align: left;}\n ( Nodes:\n [ Right\\nAligned ] { align: right; } -- label\\n text -->\n { align: left; }\n [ Left\\naligned ] )",
2619
- ],
2620
-
2621
- autolink => [
2622
- "If set to something else than 'none', will use the appropriate attribute to automatically generate the L<link>, unless L<link> is already set. See the section about labels, titles, names and links for reference.",
2623
- [ qw/label title name none inherit/ ],
2624
- { default => 'inherit', graph => 'none' },
2625
- 'title',
2626
- ],
2627
-
2628
- autotitle => [
2629
- "If set to something else than 'none', will use the appropriate attribute to automatically generate the L<title>, unless L<title> is already set. See the section about labels, titles, names and links for reference.",
2630
- [ qw/label name none link inherit/ ],
2631
- { default => 'inherit', graph => 'none' },
2632
- 'label',
2633
- ],
2634
-
2635
- autolabel => [
2636
- "Will restrict the L<label> text to N characters. N must be greater than 10. See the section about labels, titles, names and links for reference.",
2637
- # for compatibility with older versions (pre v0.49), also allow "name,N"
2638
- qr/^(name\s*,\s*)?[\d]{2,5}\z/,
2639
- { default => 'inherit', graph => '' },
2640
- '20',
2641
- undef,
2642
- "graph { autolabel: 20; autotitle: name; }\n\n[ Bonn ]\n -- Acme Travels Incorporated -->\n [ Frankfurt (Main) / Flughafen ]",
2643
- ],
2644
-
2645
- background => [
2646
- "The background color, e.g. the color B<outside> the shape. Do not confuse with L<fill>. If set to inherit, the object will inherit the L<fill> color (B<not> the background color!) of the parent e.g. the enclosing group or graph. See the section about color names and values for reference.",
2647
- undef,
2648
- # { default => 'inherit', graph => 'white', 'group.anon' => 'white', 'node.anon' => 'white' },
2649
- 'inherit',
2650
- 'rgb(255,0,0)',
2651
- ATTR_COLOR,
2652
- "[ Crimson ] { shape: circle; background: crimson; }\n -- Aqua Marine --> { background: #7fffd4; }\n [ Misty Rose ]\n { background: white; fill: rgb(255,228,221); shape: ellipse; }",
2653
- ],
2654
-
2655
- class => [
2656
- 'The subclass of the object. See the section about class names for reference.',
2657
- qr/^(|[a-zA-Z][a-zA-Z0-9_]*)\z/,
2658
- '',
2659
- 'mynodeclass',
2660
- ATTR_LCTEXT,
2661
- ],
2662
-
2663
- color => [
2664
- 'The foreground/text/label color. See the section about color names and values for reference.',
2665
- undef,
2666
- 'black',
2667
- 'rgb(255,255,0)',
2668
- ATTR_COLOR,
2669
- "[ Lime ] { color: limegreen; }\n -- label --> { color: blue; labelcolor: red; }\n [ Dark Orange ] { color: rgb(255,50%,0.01); }",
2670
- ],
2671
-
2672
- colorscheme => [
2673
- "The colorscheme to use for all color values. See the section about color names and values for reference and a list of possible values.",
2674
- '_color_scheme',
2675
- { default => 'inherit', graph => 'w3c', },
2676
- 'x11',
2677
- ATTR_STRING,
2678
- "graph { colorscheme: accent8; } [ 1 ] { fill: 1; }\n"
2679
- . " -> \n [ 3 ] { fill: 3; }\n"
2680
- . " -> \n [ 4 ] { fill: 4; }\n"
2681
- . " -> \n [ 5 ] { fill: 5; }\n"
2682
- . " -> \n [ 6 ] { fill: 6; }\n"
2683
- . " -> \n [ 7 ] { fill: 7; }\n"
2684
- . " -> \n [ 8 ] { fill: 8; }\n" ,
2685
- ],
2686
-
2687
- comment => [
2688
- "A free-form text field containing a comment on this object. This will be embedded into output formats if possible, e.g. in HTML, SVG and Graphviz, but not ASCII or Boxart.",
2689
- undef,
2690
- '',
2691
- '(C) by Tels 2007. All rights reserved.',
2692
- ATTR_STRING,
2693
- "graph { comment: German capitals; }\n [ Bonn ] --> [ Berlin ]",
2694
- ],
2695
-
2696
- fill => [
2697
- "The fill color, e.g. the color inside the shape. For the graph, this is the background color for the label. For edges, defines the color inside the arrow shape. See also L<background>. See the section about color names and values for reference.",
2698
- undef,
2699
- { default => 'white', graph => 'inherit', edge => 'inherit', group => '#a0d0ff',
2700
- 'group.anon' => 'white', 'node.anon' => 'inherit' },
2701
- 'rgb(255,0,0)',
2702
- ATTR_COLOR,
2703
- "[ Crimson ]\n {\n shape: circle;\n background: yellow;\n fill: red;\n border: 3px solid blue;\n }\n-- Aqua Marine -->\n {\n arrowstyle: filled;\n fill: red;\n }\n[ Two ]",
2704
- ],
2705
-
2706
- 'fontsize' => [
2707
- "The size of the label text, best expressed in I<em> (1.0em, 0.5em etc) or percent (100%, 50% etc)",
2708
- qr/^\d+(\.\d+)?(em|px|%)?\z/,
2709
- { default => '0.8em', graph => '1em', node => '1em', },
2710
- '50%',
2711
- undef,
2712
- "graph { fontsize: 200%; label: Sample; }\n\n ( Nodes:\n [ Big ] { fontsize: 1.5em; color: white; fill: darkred; }\n -- Small -->\n { fontsize: 0.2em; }\n [ Normal ] )",
2713
- ],
2714
-
2715
- flow => [
2716
- "The general direction in which edges will leave nodes first. On edges, influeces where the target node is place. Please see the section about <a href='hinting.html#flow'>flow control</a> for reference.",
2717
- '_direction',
2718
- { graph => 'east', default => 'inherit' },
2719
- 'south',
2720
- undef,
2721
- "graph { flow: up; }\n [ Enschede ] { flow: left; } -> [ Bielefeld ] -> [ Wolfsburg ]",
2722
- ],
2723
-
2724
- font => [
2725
- 'A prioritized list of lower-case, unquoted values, separated by a comma. Values are either font family names (like "times", "arial" etc) or generic family names (like "serif", "cursive", "monospace"), the first recognized value will be used. Always offer a generic name as the last possibility.',
2726
- '_font',
2727
- { default => 'serif', edge => 'sans-serif' },
2728
- 'arial, helvetica, sans-serif',
2729
- undef,
2730
- "graph { font: vinque, georgia, utopia, serif; label: Sample; }" .
2731
- "\n\n ( Nodes:\n [ Webdings ] { font: Dingbats, webdings; }\n".
2732
- " -- FlatLine -->\n { font: flatline; }\n [ Normal ] )",
2733
- ],
2734
-
2735
- id => [
2736
- "A unique identifier for this object, consisting only of letters, digits, or underscores.",
2737
- qr/^[a-zA-Z0-9_]+\z/,
2738
- '',
2739
- 'Bonn123',
2740
- undef,
2741
- "[ Bonn ] --> { id: 123; } [ Berlin ]",
2742
- ],
2743
-
2744
- label => [
2745
- "The text displayed as label. If not set, equals the name (for nodes) or no label (for edges, groups and the graph itself).",
2746
- undef,
2747
- undef,
2748
- 'My label',
2749
- ATTR_TEXT,
2750
- ],
2751
-
2752
- linkbase => [
2753
- 'The base URL prepended to all generated links. See the section about links for reference.',
2754
- undef,
2755
- { default => 'inherit', graph => '/wiki/index.php/', },
2756
- 'http://en.wikipedia.org/wiki/',
2757
- ATTR_URL,
2758
- ],
2759
-
2760
- link => [
2761
- 'The link part, appended onto L<linkbase>. See the section about links for reference.',
2762
- undef,
2763
- '',
2764
- 'Graph',
2765
- ATTR_TEXT,
2766
- <<LINK_EOF
2767
- node {
2768
- autolink: name;
2769
- textstyle: none;
2770
- fontsize: 1.1em;
2771
- }
2772
- graph {
2773
- linkbase: http://de.wikipedia.org/wiki/;
2774
- }
2775
- edge {
2776
- textstyle: overline;
2777
- }
2778
-
2779
- [] --> [ Friedrichshafen ]
2780
- -- Schiff --> { autolink: label; color: orange; title: Vrooom!; }
2781
- [ Immenstaad ] { color: green; } --> [ Hagnau ]
2782
- LINK_EOF
2783
- ],
2784
-
2785
- title => [
2786
- "The text displayed as mouse-over for nodes/edges, or as the title for the graph. If empty, no title will be generated unless L<autotitle> is set.",
2787
- undef,
2788
- '',
2789
- 'My title',
2790
- ATTR_TEXT,
2791
- ],
2792
-
2793
- format => [
2794
- "The formatting language of the label. The default, C<none> means nothing special will be done. When set to C<pod>, formatting codes like <code>B&lt;bold&gt;</code> will change the formatting of the label. See the section about label text formatting for reference.",
2795
- [ 'none', 'pod' ],
2796
- 'none',
2797
- 'pod',
2798
- undef,
2799
- <<EOF
2800
- graph {
2801
- format: pod;
2802
- label: I am B<bold> and I<italic>;
2803
- }
2804
- node { format: pod; }
2805
- edge { format: pod; }
2806
-
2807
- [ U<B<bold and underlined>> ]
2808
- --> { label: "S<Fähre>"; }
2809
- [ O<Konstanz> ]
2810
- EOF
2811
- ],
2812
-
2813
- textstyle => [
2814
- "The style of the label text. Either 'none', or any combination (separated with spaces) of 'underline', 'overline', 'bold', 'italic', 'line-through'. 'none' disables underlines on links.",
2815
- 'text_style',
2816
- '',
2817
- 'underline italic bold',
2818
- undef,
2819
- <<EOF
2820
- graph {
2821
- fontsize: 150%;
2822
- label: Verbindung;
2823
- textstyle: bold italic;
2824
- }
2825
- node {
2826
- textstyle: underline bold;
2827
- fill: #ffd080;
2828
- }
2829
- edge {
2830
- textstyle: italic bold overline;
2831
- }
2832
-
2833
- [ Meersburg ] { fontsize: 2em; }
2834
- -- F\x{e4}hre --> { fontsize: 1.2em; color: red; }
2835
- [ Konstanz ]
2836
- EOF
2837
- ],
2838
-
2839
- textwrap => [
2840
- "The default C<none> makes the label text appear exactly as it was written, with <a href='syntax.html'>manual line breaks</a> applied. When set to a positive number, the label text will be wrapped after this number of characters. When set to C<auto>, the label text will be wrapped to make the node size as small as possible, depending on output format this may even be dynamic. When not C<none>, manual line breaks and alignments on them are ignored.",
2841
- qr/^(auto|none|\d{1,4})/,
2842
- { default => 'inherit', graph => 'none' },
2843
- 'auto',
2844
- undef,
2845
- "node { textwrap: auto; }\n ( Nodes:\n [ Frankfurt (Oder) liegt an der\n ostdeutschen Grenze und an der Oder ] -->\n [ Städte innerhalb der\n Ost-Westfahlen Region mit sehr langen Namen] )",
2846
- ],
2847
- },
2848
-
2849
- node => {
2850
- bordercolor => [
2851
- 'The color of the L<border>. See the section about color names and values for reference.',
2852
- undef,
2853
- { default => '#000000' },
2854
- 'rgb(255,255,0)',
2855
- ATTR_COLOR,
2856
- "node { border: black bold; }\n[ Black ]\n --> [ Red ] { bordercolor: red; }\n --> [ Green ] { bordercolor: green; }",
2857
- ],
2858
-
2859
- borderstyle => [
2860
- 'The style of the L<border>. The special styles "bold", "broad", "wide", "double-dash" and "bold-dash" will set and override the L<borderwidth>.',
2861
- [ qw/none solid dotted dashed dot-dash dot-dot-dash double wave bold bold-dash broad double-dash wide/ ],
2862
- { default => 'none', 'node.anon' => 'none', 'group.anon' => 'none', node => 'solid', group => 'dashed' },
2863
- 'dotted',
2864
- undef,
2865
- "node { border: dotted; }\n[ Dotted ]\n --> [ Dashed ] { borderstyle: dashed; }\n --> [ broad ] { borderstyle: broad; }",
2866
- ],
2867
-
2868
- borderwidth => [
2869
- 'The width of the L<border>. Certain L<border>-styles will override the width.',
2870
- qr/^\d+(px|em)?\z/,
2871
- '1',
2872
- '2px',
2873
- ],
2874
-
2875
- border => [
2876
- 'The border. Can be any combination of L<borderstyle>, L<bordercolor> and L<borderwidth>.',
2877
- undef,
2878
- { default => 'none', 'node.anon' => 'none', 'group.anon' => 'none', node => 'solid 1px #000000', group => 'dashed 1px #000000' },
2879
- 'dotted red',
2880
- undef,
2881
- "[ Normal ]\n --> [ Bold ] { border: bold; }\n --> [ Broad ] { border: broad; }\n --> [ Wide ] { border: wide; }\n --> [ Bold-Dash ] { border: bold-dash; }",
2882
- ],
2883
-
2884
- basename => [
2885
- "Controls the base name of an autosplit node. Ignored for all other nodes. Unless set, it is generated automatically from the node parts. Please see the section about <a href='hinting.html#autosplit'>autosplit</a> for reference.",
2886
- undef,
2887
- '',
2888
- '123',
2889
- undef,
2890
- "[ A|B|C ] { basename: A } [ 1 ] -> [ A.2 ]\n [ A|B|C ] [ 2 ] -> [ ABC.2 ]",
2891
- ],
2892
-
2893
- group => [
2894
- "Puts the node into this group.",
2895
- undef,
2896
- '',
2897
- 'Cities',
2898
- undef,
2899
- "[ A ] { group: Cities:; } ( Cities: [ B ] ) [ A ] --> [ B ]",
2900
- ],
2901
-
2902
- size => [
2903
- 'The size of the node in columns and rows. Must be greater than 1 in each direction.',
2904
- qr/^\d+\s*,\s*\d+\z/,
2905
- '1,1',
2906
- '3,2',
2907
- ],
2908
- rows => [
2909
- 'The size of the node in rows. See also L<size>.',
2910
- qr/^\d+\z/,
2911
- '1',
2912
- '3',
2913
- ],
2914
- columns => [
2915
- 'The size of the node in columns. See also L<size>.',
2916
- qr/^\d+\z/,
2917
- '1',
2918
- '2',
2919
- ],
2920
-
2921
- offset => [
2922
- 'The offset of this node from the L<origin> node, in columns and rows. Only used if you also set the L<origin> node.',
2923
- qr/^[+-]?\d+\s*,\s*[+-]?\d+\z/,
2924
- '0,0',
2925
- '3,2',
2926
- undef,
2927
- "[ A ] -> [ B ] { origin: A; offset: 2,2; }",
2928
- ],
2929
-
2930
- origin => [
2931
- 'The name of the node, that this node is relativ to. See also L<offset>.',
2932
- undef,
2933
- '',
2934
- 'Cluster A',
2935
- ],
2936
-
2937
- pointshape => [
2938
- "Controls the style of a node that has a L<shape> of 'point'.",
2939
- [ qw/star square dot circle cross diamond invisible x/ ],
2940
- 'star',
2941
- 'square',
2942
- undef,
2943
- "node { shape: point; }\n\n [ A ]".
2944
- "\n -> [ B ] { pointshape: circle; }" .
2945
- "\n -> [ C ] { pointshape: cross; }" .
2946
- "\n -> [ D ] { pointshape: diamond; }" .
2947
- "\n -> [ E ] { pointshape: dot; }" .
2948
- "\n -> [ F ] { pointshape: invisible; }" .
2949
- "\n -> [ G ] { pointshape: square; }" .
2950
- "\n -> [ H ] { pointshape: star; }" .
2951
- "\n -> [ I ] { pointshape: x; }" .
2952
- "\n -> [ ☯ ] { shape: none; }"
2953
- ],
2954
-
2955
- pointstyle => [
2956
- "Controls the style of the L<pointshape> of a node that has a L<shape> of 'point'. " .
2957
- "Note for backwards compatibility reasons, the shape names 'star', 'square', 'dot', 'circle', 'cross', 'diamond' and 'invisible' ".
2958
- "are also supported, but should not be used here, instead set them via L<pointshape>.",
2959
- [ qw/closed filled star square dot circle cross diamond invisible x/ ],
2960
- 'filled',
2961
- 'open',
2962
- undef,
2963
- "node { shape: point; pointstyle: closed; pointshape: diamond; }\n\n [ A ] --> [ B ] { pointstyle: filled; }",
2964
- ],
2965
-
2966
- rank => [
2967
- "The rank of the node, used by the layouter to find the order and placement of nodes. " .
2968
- "Set to C<auto> (the default), C<same> (usefull for node lists) or a positive number. " .
2969
- "See the section about ranks for reference and more examples.",
2970
- qr/^(auto|same|\d{1,6})\z/,
2971
- 'auto',
2972
- 'same',
2973
- undef,
2974
- "[ Bonn ], [ Berlin ] { rank: same; }\n [ Bonn ] -> [ Cottbus ] -> [ Berlin ]",
2975
- ],
2976
-
2977
- rotate => [
2978
- "The rotation of the node shape, either an absolute value (like C<south>, C<up>, C<down> or C<123>), or a relative value (like C<+12>, C<-90>, C<left>, C<right>). For relative angles, the rotation will be based on the node's L<flow>. Rotation is clockwise.",
2979
- undef,
2980
- '0',
2981
- '180',
2982
- ATTR_ANGLE,
2983
- "[ Bonn ] { rotate: 45; } -- ICE --> \n [ Berlin ] { shape: triangle; rotate: -90; }",
2984
- ],
2985
-
2986
- shape => [
2987
- "The shape of the node. Nodes with shape 'point' (see L<pointshape>) have a fixed size and do not display their label. The border of such a node is the outline of the C<pointshape>, and the fill is the inside of the C<pointshape>. When the C<shape> is set to the value 'img', the L<label> will be interpreted as an external image resource to display. In this case attributes like L<color>, L<fontsize> etc. are ignored.",
2988
- [ qw/ circle diamond edge ellipse hexagon house invisible invhouse invtrapezium invtriangle octagon parallelogram pentagon
2989
- point triangle trapezium septagon rect rounded none img/ ],
2990
- 'rect',
2991
- 'circle',
2992
- undef,
2993
- "[ Bonn ] -> \n [ Berlin ] { shape: circle; }\n -> [ Regensburg ] { shape: rounded; }\n -> [ Ulm ] { shape: point; }\n -> [ Wasserburg ] { shape: invisible; }\n -> [ Augsburg ] { shape: triangle; }\n -> [ House ] { shape: img; label: img/house.png;\n border: none; title: My House; fill: inherit; }",
2994
- ],
2995
-
2996
- }, # node
2997
-
2998
- graph => {
2999
-
3000
- bordercolor => [
3001
- 'The color of the L<border>. See the section about color names and values for reference.',
3002
- undef,
3003
- { default => '#000000' },
3004
- 'rgb(255,255,0)',
3005
- ATTR_COLOR,
3006
- "node { border: black bold; }\n[ Black ]\n --> [ Red ] { bordercolor: red; }\n --> [ Green ] { bordercolor: green; }",
3007
- ],
3008
-
3009
- borderstyle => [
3010
- 'The style of the L<border>. The special styles "bold", "broad", "wide", "double-dash" and "bold-dash" will set and override the L<borderwidth>.',
3011
- [ qw/none solid dotted dashed dot-dash dot-dot-dash double wave bold bold-dash broad double-dash wide/ ],
3012
- { default => 'none', 'node.anon' => 'none', 'group.anon' => 'none', node => 'solid', group => 'dashed' },
3013
- 'dotted',
3014
- undef,
3015
- "node { border: dotted; }\n[ Dotted ]\n --> [ Dashed ] { borderstyle: dashed; }\n --> [ broad ] { borderstyle: broad; }",
3016
- ],
3017
-
3018
- borderwidth => [
3019
- 'The width of the L<border>. Certain L<border>-styles will override the width.',
3020
- qr/^\d+(px|em)?\z/,
3021
- '1',
3022
- '2px',
3023
- ],
3024
-
3025
- border => [
3026
- 'The border. Can be any combination of L<borderstyle>, L<bordercolor> and L<borderwidth>.',
3027
- undef,
3028
- { default => 'none', 'node.anon' => 'none', 'group.anon' => 'none', node => 'solid 1px #000000', group => 'dashed 1px #000000' },
3029
- 'dotted red',
3030
- undef,
3031
- "[ Normal ]\n --> [ Bold ] { border: bold; }\n --> [ Broad ] { border: broad; }\n --> [ Wide ] { border: wide; }\n --> [ Bold-Dash ] { border: bold-dash; }",
3032
- ],
3033
-
3034
- gid => [
3035
- "A unique ID for the graph. Usefull if you want to include two graphs into one HTML page.",
3036
- qr/^\d+\z/,
3037
- '',
3038
- '123',
3039
- ],
3040
-
3041
- labelpos => [
3042
- "The position of the graph label.",
3043
- [ qw/top bottom/ ],
3044
- 'top',
3045
- 'bottom',
3046
- ATTR_LIST,
3047
- "graph { labelpos: bottom; label: My Graph; }\n\n [ Buxtehude ] -> [ Fuchsberg ]\n"
3048
- ],
3049
-
3050
- output => [
3051
- "The desired output format. Only used when calling Graph::Easy::output(), or by mediawiki-graph.",
3052
- [ qw/ascii html svg graphviz boxart debug/ ],
3053
- '',
3054
- 'ascii',
3055
- ATTR_LIST,
3056
- "graph { output: debug; }"
3057
- ],
3058
-
3059
- root => [
3060
- "The name of the root node, given as hint to the layouter to start the layout there. When not set, the layouter will pick a node at semi-random.",
3061
- undef,
3062
- '',
3063
- 'My Node',
3064
- ATTR_TEXT,
3065
- "graph { root: B; }\n # B will be at the left-most place\n [ A ] --> [ B ] --> [ C ] --> [ D ] --> [ A ]",
3066
- ],
3067
-
3068
- type => [
3069
- "The type of the graph, either undirected or directed.",
3070
- [ qw/directed undirected/ ],
3071
- 'directed',
3072
- 'undirected',
3073
- ATTR_LIST,
3074
- "graph { type: undirected; }\n [ A ] --> [ B ]",
3075
- ],
3076
-
3077
- }, # graph
3078
-
3079
- edge => {
3080
-
3081
- style => [
3082
- 'The line style of the edge. When set on the general edge class, this attribute changes only the style of all solid edges to the specified one.',
3083
- [ qw/solid dotted dashed dot-dash dot-dot-dash bold bold-dash double-dash double wave broad wide invisible/], # broad-dash wide-dash/ ],
3084
- 'solid',
3085
- 'dotted',
3086
- undef,
3087
- "[ A ] -- solid --> [ B ]\n .. dotted ..> [ C ]\n - dashed - > [ D ]\n -- bold --> { style: bold; } [ E ]\n -- broad --> { style: broad; } [ F ]\n -- wide --> { style: wide; } [ G ]",
3088
- ],
3089
-
3090
- arrowstyle => [
3091
- 'The style of the arrow. Open arrows are vee-shaped and the bit inside the arrow has the color of the L<background>. Closed arrows are triangle shaped, with a background-color fill. Filled arrows are closed, too, but use the L<fill> color for the inside. If the fill color is not set, the L<color> attribute will be used instead. An C<arrowstyle> of none creates undirected edges just like "[A] -- [B]" would do.',
3092
- [ qw/none open closed filled/ ],
3093
- 'open',
3094
- 'closed',
3095
- undef,
3096
- "[ A ] -- open --> [ B ]\n -- closed --> { arrowstyle: closed; } [ C ]\n -- filled --> { arrowstyle: filled; } [ D ]\n -- filled --> { arrowstyle: filled; fill: lime; } [ E ]\n -- none --> { arrowstyle: none; } [ F ]",
3097
- ],
3098
-
3099
- arrowshape => [
3100
- 'The basic shape of the arrow. Can be combined with each of L<arrowstyle>.',
3101
- [ qw/triangle box dot inv line diamond cross x/ ],
3102
- 'triangle',
3103
- 'box',
3104
- undef,
3105
- "[ A ] -- triangle --> [ B ]\n -- box --> { arrowshape: box; } [ C ]\n" .
3106
- " -- inv --> { arrowshape: inv; } [ D ]\n -- diamond --> { arrowshape: diamond; } [ E ]\n" .
3107
- " -- dot --> { arrowshape: dot; } [ F ]\n" .
3108
- " -- line --> { arrowshape: line; } [ G ] \n" .
3109
- " -- plus --> { arrowshape: cross; } [ H ] \n" .
3110
- " -- x --> { arrowshape: x; } [ I ] \n\n" .
3111
- "[ a ] -- triangle --> { arrowstyle: filled; } [ b ]\n".
3112
- " -- box --> { arrowshape: box; arrowstyle: filled; } [ c ]\n" .
3113
- " -- inv --> { arrowshape: inv; arrowstyle: filled; } [ d ]\n" .
3114
- " -- diamond --> { arrowshape: diamond; arrowstyle: filled; } [ e ]\n" .
3115
- " -- dot --> { arrowshape: dot; arrowstyle: filled; } [ f ]\n" .
3116
- " -- line --> { arrowshape: line; arrowstyle: filled; } [ g ] \n" .
3117
- " -- plus --> { arrowshape: cross; arrowstyle: filled; } [ h ] \n" .
3118
- " -- x --> { arrowshape: x; arrowstyle: filled; } [ i ] \n",
3119
- ],
3120
-
3121
- labelcolor => [
3122
- 'The text color for the label. If unspecified, will fall back to L<color>. See the section about color names and values for reference.',
3123
- undef,
3124
- 'black',
3125
- 'rgb(255,255,0)',
3126
- ATTR_COLOR,
3127
- "[ Bonn ] -- ICE --> { labelcolor: blue; }\n [ Berlin ]",
3128
- ],
3129
-
3130
- start => [
3131
- 'The starting port of this edge. See <a href="hinting.html#joints">the section about joints</a> for reference.',
3132
- qr/^(south|north|east|west|left|right|front|back)(\s*,\s*-?\d{1,4})?\z/,
3133
- '',
3134
- 'front, 0',
3135
- ATTR_PORT,
3136
- "[ Bonn ] -- NORTH --> { start: north; end: north; } [ Berlin ]",
3137
- ],
3138
-
3139
- end => [
3140
- 'The ending port of this edge. See <a href="hinting.html#joints">the section about joints</a> for reference.',
3141
- qr/^(south|north|east|west|right|left|front|back)(\s*,\s*-?\d{1,4})?\z/,
3142
- '',
3143
- 'back, 0',
3144
- ATTR_PORT,
3145
- "[ Bonn ] -- NORTH --> { start: south; end: east; } [ Berlin ]",
3146
- ],
3147
-
3148
- minlen => [
3149
- 'The minimum length of the edge, in cells. Defaults to 1. The minimum length is ' .
3150
- 'automatically increased for edges with joints.',
3151
- undef,
3152
- '1',
3153
- '4',
3154
- ATTR_UINT,
3155
- "[ Bonn ] -- longer --> { minlen: 3; } [ Berlin ]\n[ Bonn ] --> [ Potsdam ] { origin: Bonn; offset: 2,2; }",
3156
- ],
3157
-
3158
- autojoin => [
3159
- 'Controls whether the layouter can join this edge automatically with other edges leading to the same node. C<never> means this edge will never joined with another edge automatically, C<always> means always (if possible), even if the attributes on the edges do not match. C<equals> means only edges with the same set of attributes will be automatically joined together. See also C<autosplit>.',
3160
- [qw/never always equals/],
3161
- 'never',
3162
- 'always',
3163
- undef,
3164
- "[ Bonn ], [ Aachen ]\n -- 1 --> { autojoin: equals; } [ Berlin ]",
3165
- ],
3166
-
3167
- autosplit => [
3168
- 'Controls whether the layouter replace multiple edges leading from one node to other nodes with one edge splitting up. C<never> means this edge will never be part of such a split, C<always> means always (if possible), even if the attributes on the edges do not match. C<equals> means only edges with the same set of attributes will be automatically split up. See also C<autojoin>.',
3169
- [qw/never always equals/],
3170
- 'never',
3171
- 'always',
3172
- undef,
3173
- "[ Bonn ]\n -- 1 --> { autosplit: equals; } [ Berlin ], [ Aachen ]",
3174
- ],
3175
-
3176
- }, # edge
3177
-
3178
- group => {
3179
- bordercolor => [
3180
- 'The color of the L<border>. See the section about color names and values for reference.',
3181
- undef,
3182
- { default => '#000000' },
3183
- 'rgb(255,255,0)',
3184
- ATTR_COLOR,
3185
- "node { border: black bold; }\n[ Black ]\n --> [ Red ] { bordercolor: red; }\n --> [ Green ] { bordercolor: green; }",
3186
- ],
3187
-
3188
- borderstyle => [
3189
- 'The style of the L<border>. The special styles "bold", "broad", "wide", "double-dash" and "bold-dash" will set and override the L<borderwidth>.',
3190
- [ qw/none solid dotted dashed dot-dash dot-dot-dash double wave bold bold-dash broad double-dash wide/ ],
3191
- { default => 'none', 'node.anon' => 'none', 'group.anon' => 'none', node => 'solid', group => 'dashed' },
3192
- 'dotted',
3193
- undef,
3194
- "node { border: dotted; }\n[ Dotted ]\n --> [ Dashed ] { borderstyle: dashed; }\n --> [ broad ] { borderstyle: broad; }",
3195
- ],
3196
-
3197
- borderwidth => [
3198
- 'The width of the L<border>. Certain L<border>-styles will override the width.',
3199
- qr/^\d+(px|em)?\z/,
3200
- '1',
3201
- '2px',
3202
- ],
3203
-
3204
- border => [
3205
- 'The border. Can be any combination of L<borderstyle>, L<bordercolor> and L<borderwidth>.',
3206
- undef,
3207
- { default => 'none', 'node.anon' => 'none', 'group.anon' => 'none', node => 'solid 1px #000000', group => 'dashed 1px #000000' },
3208
- 'dotted red',
3209
- undef,
3210
- "[ Normal ]\n --> [ Bold ] { border: bold; }\n --> [ Broad ] { border: broad; }\n --> [ Wide ] { border: wide; }\n --> [ Bold-Dash ] { border: bold-dash; }",
3211
- ],
3212
-
3213
- nodeclass => [
3214
- 'The class into which all nodes of this group are put.',
3215
- qr/^(|[a-zA-Z][a-zA-Z0-9_]*)\z/,
3216
- '',
3217
- 'cities',
3218
- ],
3219
-
3220
- edgeclass => [
3221
- 'The class into which all edges defined in this group are put. This includes edges that run between two nodes belonging to the same group.',
3222
- qr/^(|[a-zA-Z][a-zA-Z0-9_]*)\z/,
3223
- '',
3224
- 'connections',
3225
- ],
3226
-
3227
- rank => [
3228
- "The rank of the group, used by the layouter to find the order and placement of group. " .
3229
- "Set to C<auto> (the default), C<same> or a positive number. " .
3230
- "See the section about ranks for reference and more examples.",
3231
- qr/^(auto|same|\d{1,6})\z/,
3232
- 'auto',
3233
- 'same',
3234
- undef,
3235
- "( Cities: [ Bonn ], [ Berlin ] ) { rank: 0; } ( Rivers: [ Rhein ], [ Sieg ] ) { rank: 0; }",
3236
- ],
3237
-
3238
- root => [
3239
- "The name of the root node, given as hint to the layouter to start the layout there. When not set, the layouter will pick a node at semi-random.",
3240
- undef,
3241
- '',
3242
- 'My Node',
3243
- ATTR_TEXT,
3244
- "( Cities: [ A ] --> [ B ] --> [ C ] --> [ D ] --> [ A ] ) { root: B; }",
3245
- ],
3246
-
3247
- group => [
3248
- "Puts the group inside this group, nesting the two groups inside each other.",
3249
- undef,
3250
- '',
3251
- 'Cities',
3252
- undef,
3253
- "( Cities: [ Bonn ] ) ( Rivers: [ Rhein ] ) { group: Cities:; }",
3254
- ],
3255
-
3256
- labelpos => [
3257
- "The position of the group label.",
3258
- [ qw/top bottom/ ],
3259
- 'top',
3260
- 'bottom',
3261
- ATTR_LIST,
3262
- "group { labelpos: bottom; }\n\n ( My Group: [ Buxtehude ] -> [ Fuchsberg ] )\n"
3263
- ],
3264
-
3265
- }, # group
3266
-
3267
- # These entries will be allowed temporarily during Graphviz parsing for
3268
- # intermidiate values, like "shape=record".
3269
- special => { },
3270
- }; # end of attribute definitions
3271
-
3272
- sub _allow_special_attributes
3273
- {
3274
- # store a hash with special temp. attributes
3275
- my ($self, $att) = @_;
3276
- $attributes->{special} = $att;
3277
- }
3278
-
3279
- sub _drop_special_attributes
3280
- {
3281
- # drop the hash with special temp. attributes
3282
- my ($self) = @_;
3283
-
3284
- $attributes->{special} = {};
3285
- }
3286
-
3287
- sub _attribute_entries
3288
- {
3289
- # for building the manual page
3290
- $attributes;
3291
- }
3292
-
3293
- sub border_attribute
3294
- {
3295
- # Return "1px solid red" from the border-(style|color|width) attributes,
3296
- # mainly used by as_txt() output. Does not use colorscheme!
3297
- my ($self, $class) = @_;
3298
-
3299
- my ($style,$width,$color);
3300
-
3301
- my $g = $self; $g = $self->{graph} if ref($self->{graph});
3302
-
3303
- my ($def_style, $def_color, $def_width);
3304
-
3305
- # XXX TODO need no_default_attribute()
3306
- if (defined $class)
3307
- {
3308
- $style = $g->attribute($class, 'borderstyle');
3309
- return $style if $style eq 'none';
3310
-
3311
- $def_style = $g->default_attribute('borderstyle');
3312
-
3313
- $width = $g->attribute($class,'borderwidth');
3314
- $def_width = $g->default_attribute($class,'borderwidth');
3315
- $width = '' if $def_width eq $width;
3316
-
3317
- $color = $g->attribute($class,'bordercolor');
3318
- $def_color = $g->default_attribute($class,'bordercolor');
3319
- $color = '' if $def_color eq $color;
3320
- }
3321
- else
3322
- {
3323
- $style = $self->attribute('borderstyle');
3324
- return $style if $style eq 'none';
3325
-
3326
- $def_style = $self->default_attribute('borderstyle');
3327
-
3328
- $width = $self->attribute('borderwidth');
3329
- $def_width = $self->default_attribute('borderwidth');
3330
- $width = '' if $def_width eq $width;
3331
-
3332
- $color = $self->attribute('bordercolor');
3333
- $def_color = $self->default_attribute('bordercolor');
3334
- $color = '' if $def_color eq $color;
3335
- }
3336
-
3337
- return '' if $def_style eq $style and $color eq '' && $width eq '';
3338
-
3339
- Graph::Easy::_border_attribute($style, $width, $color);
3340
- }
3341
-
3342
- sub _unknown_attribute
3343
- {
3344
- # either just warn, or raise an error for unknown attributes
3345
- my ($self, $name, $class) = @_;
3346
-
3347
- if ($self->{_warn_on_unknown_attributes})
3348
- {
3349
- $self->warn("Ignoring unknown attribute '$name' for class $class")
3350
- }
3351
- else
3352
- {
3353
- $self->error("Error in attribute: '$name' is not a valid attribute name for a $class");
3354
- }
3355
- return;
3356
- }
3357
-
3358
- sub default_attribute
3359
- {
3360
- # Return the default value for the attribute.
3361
- my ($self, $class, $name) = @_;
3362
-
3363
- # allow $self->default_attribute('fill');
3364
- if (scalar @_ == 2)
3365
- {
3366
- $name = $class;
3367
- $class = $self->{class} || 'graph';
3368
- }
3369
-
3370
- # get the base class: node.foo => node
3371
- my $base_class = $class; $base_class =~ s/\..*//;
3372
-
3373
- # Remap alias names without "-" to their hyphenated version:
3374
- $name = $att_aliases->{$name} if exists $att_aliases->{$name};
3375
-
3376
- # "x-foo-bar" is a custom attribute, so allow it always. The name must
3377
- # consist only of letters and hyphens, and end in a letter or number.
3378
- # Hyphens must be separated by letters. Custom attributes do not have a default.
3379
- return '' if $name =~ $qr_custom_attribute;
3380
-
3381
- # prevent ->{special}->{node} from springing into existance
3382
- my $s = $attributes->{special}; $s = $s->{$class} if exists $s->{$class};
3383
-
3384
- my $entry = $s->{$name} ||
3385
- $attributes->{all}->{$name} ||
3386
- $attributes->{$base_class}->{$name};
3387
-
3388
- # Didn't found an entry:
3389
- return $self->_unknown_attribute($name,$class) unless ref($entry);
3390
-
3391
- # get the default attribute from the entry
3392
- my $def = $entry->[ ATTR_DEFAULT_SLOT ]; my $val = $def;
3393
-
3394
- # "node.subclass" gets the default from "node", 'edge' from 'default':
3395
- # " { default => 'foo', 'node.anon' => 'none', node => 'solid' }":
3396
- if (ref $def)
3397
- {
3398
- $val = $def->{$class};
3399
- $val = $def->{$base_class} unless defined $val;
3400
- $val = $def->{default} unless defined $val;
3401
- }
3402
-
3403
- $val;
3404
- }
3405
-
3406
- sub raw_attribute
3407
- {
3408
- # Return either the raw attribute set on an object (honoring inheritance),
3409
- # or undef for when that specific attribute is not set. Does *not*
3410
- # inspect class attributes.
3411
- my ($self, $name) = @_;
3412
-
3413
- # Remap alias names without "-" to their hyphenated version:
3414
- $name = $att_aliases->{$name} if exists $att_aliases->{$name};
3415
-
3416
- my $class = $self->{class} || 'graph';
3417
- my $base_class = $class; $base_class =~ s/\..*//;
3418
-
3419
- # prevent ->{special}->{node} from springing into existance
3420
- my $s = $attributes->{special}; $s = $s->{$class} if exists $s->{$class};
3421
-
3422
- my $entry = $s->{$name} ||
3423
- $attributes->{all}->{$name} ||
3424
- $attributes->{$base_class}->{$name};
3425
-
3426
- # create a fake entry for custom attributes
3427
- $entry = [ '', undef, '', '', ATTR_STRING, '' ]
3428
- if $name =~ $qr_custom_attribute;
3429
-
3430
- # Didn't found an entry:
3431
- return $self->_unknown_attribute($name,$class) unless ref($entry);
3432
-
3433
- my $type = $entry->[ ATTR_TYPE_SLOT ] || ATTR_STRING;
3434
-
3435
- my $val;
3436
-
3437
- ###########################################################################
3438
- # Check the object directly first
3439
- my $a = $self->{att};
3440
- if (exists $a->{graph})
3441
- {
3442
- # for graphs, look directly in the class to save time:
3443
- $val = $a->{graph}->{$name}
3444
- if exists $a->{graph}->{$name};
3445
- }
3446
- else
3447
- {
3448
- $val = $a->{$name} if exists $a->{$name};
3449
- }
3450
-
3451
- # For "background", and objects that are in a group, we inherit "fill":
3452
- $val = $self->{group}->color_attribute('fill')
3453
- if $name eq 'background' && ref $self->{group};
3454
-
3455
- return $val if !defined $val || $val ne 'inherit' ||
3456
- $name =~ /^x-([a-z_]+-)*[a-z_]+([0-9]*)\z/;
3457
-
3458
- # $val is defined, and "inherit" (and it is not a special attribute)
3459
-
3460
- # for graphs, there is nothing to inherit from
3461
- return $val if $class eq 'graph';
3462
-
3463
- # we try classes in this order:
3464
- # "node", "graph"
3465
-
3466
- my @tries = ();
3467
- # if the class is already "node", skip it:
3468
- if ($class =~ /\./)
3469
- {
3470
- my $parent_class = $class; $parent_class =~ s/\..*//;
3471
- push @tries, $parent_class;
3472
- }
3473
-
3474
- # If not part of a graph, we cannot have class attributes, but
3475
- # we still can find default attributes. So fake a "graph":
3476
- my $g = $self->{graph}; # for objects in a graph
3477
- $g = { att => {} } unless ref($g); # for objects not in a graph
3478
-
3479
- $val = undef;
3480
- for my $try (@tries)
3481
- {
3482
- # print STDERR "# Trying class $try for attribute $name\n";
3483
-
3484
- my $att = $g->{att}->{$try};
3485
-
3486
- $val = $att->{$name} if exists $att->{$name};
3487
-
3488
- # value was not defined, so get the default value
3489
- if (!defined $val)
3490
- {
3491
- my $def = $entry->[ ATTR_DEFAULT_SLOT ]; $val = $def;
3492
-
3493
- # "node.subclass" gets the default from "node", 'edge' from 'default':
3494
- # " { default => 'foo', 'node.anon' => 'none', node => 'solid' }":
3495
- if (ref $def)
3496
- {
3497
- $val = $def->{$try};
3498
- if (!defined $val && $try =~ /\./)
3499
- {
3500
- my $base = $try; $base =~ s/\..*//;
3501
- $val = $def->{$base};
3502
- }
3503
- $val = $def->{default} unless defined $val;
3504
- }
3505
- }
3506
- # $val must now be defined, because default value must exist.
3507
-
3508
- # print STDERR "# Found '$val' for $try\n";
3509
-
3510
- if ($name ne 'label')
3511
- {
3512
- $self->warn("Uninitialized default for attribute '$name' on class '$try'\n")
3513
- unless defined $val;
3514
- }
3515
-
3516
- return $val if $type >= ATTR_NO_INHERIT;
3517
-
3518
- # got some value other than inherit or already at top of tree:
3519
- return $val if defined $val && $val ne 'inherit';
3520
-
3521
- # try next class in inheritance tree
3522
- $val = undef;
3523
- }
3524
-
3525
- $val;
3526
- }
3527
-
3528
- sub color_attribute
3529
- {
3530
- # Just like get_attribute(), but for colors, and returns them as hex,
3531
- # using the current colorscheme.
3532
- my $self = shift;
3533
-
3534
- my $color = $self->attribute(@_);
3535
-
3536
- if ($color !~ /^#/ && $color ne '')
3537
- {
3538
- my $scheme = $self->attribute('colorscheme');
3539
- $color = Graph::Easy->color_as_hex($color, $scheme);
3540
- }
3541
-
3542
- $color;
3543
- }
3544
-
3545
- sub raw_color_attribute
3546
- {
3547
- # Just like raw_attribute(), but for colors, and returns them as hex,
3548
- # using the current colorscheme.
3549
- my $self = shift;
3550
-
3551
- my $color = $self->raw_attribute(@_);
3552
- return undef unless defined $color; # default to undef
3553
-
3554
- if ($color !~ /^#/ && $color ne '')
3555
- {
3556
- my $scheme = $self->attribute('colorscheme');
3557
- $color = Graph::Easy->color_as_hex($color, $scheme);
3558
- }
3559
-
3560
- $color;
3561
- }
3562
-
3563
- sub _attribute_entry
3564
- {
3565
- # return the entry defining an attribute, based on the attribute name
3566
- my ($self, $class, $name) = @_;
3567
-
3568
- # font-size => fontsize
3569
- $name = $att_aliases->{$name} if exists $att_aliases->{$name};
3570
-
3571
- my $base_class = $class; $base_class =~ s/\.(.*)//;
3572
-
3573
- # prevent ->{special}->{node} from springing into existance
3574
- my $s = $attributes->{special}; $s = $s->{$class} if exists $s->{$class};
3575
- my $entry = $s->{$name} ||
3576
- $attributes->{all}->{$name} ||
3577
- $attributes->{$base_class}->{$name};
3578
-
3579
- $entry;
3580
- }
3581
-
3582
- sub attribute
3583
- {
3584
- my ($self, $class, $name) = @_;
3585
-
3586
- my $three_arg = 0;
3587
- if (scalar @_ == 3)
3588
- {
3589
- # $self->attribute($class,$name) if only allowed on graphs
3590
- return $self->error("Calling $self->attribute($class,$name) only allowed for graphs")
3591
- if exists $self->{graph};
3592
-
3593
- if ($class !~ /^(node|group|edge|graph\z)/)
3594
- {
3595
- return $self->error ("Illegal class '$class' when trying to get attribute '$name'");
3596
- }
3597
- $three_arg = 1;
3598
- return $self->border_attribute($class) if $name eq 'border'; # virtual attribute
3599
- }
3600
- else
3601
- {
3602
- # allow calls of the style get_attribute('background');
3603
- $name = $class;
3604
- $class = $self->{class} || 'graph' if $name eq 'class'; # avoid deep recursion
3605
- if ($name ne 'class')
3606
- {
3607
- $class = $self->{cache}->{class};
3608
- $class = $self->class() unless defined $class;
3609
- }
3610
-
3611
- return $self->border_attribute() if $name eq 'border'; # virtual attribute
3612
- return join (",",$self->size()) if $name eq 'size'; # virtual attribute
3613
- }
3614
-
3615
- # print STDERR "# called attribute($class,$name)\n";
3616
-
3617
- # font-size => fontsize
3618
- $name = $att_aliases->{$name} if exists $att_aliases->{$name};
3619
-
3620
- my $base_class = $class; $base_class =~ s/\.(.*)//;
3621
- my $sub_class = $1; $sub_class = '' unless defined $sub_class;
3622
- if ($name eq 'class')
3623
- {
3624
- # "[A] { class: red; }" => "red"
3625
- return $sub_class if $sub_class ne '';
3626
- # "node { class: green; } [A]" => "green": fall through and let the code
3627
- # below look up the attribute or fall back to the default '':
3628
- }
3629
-
3630
- # prevent ->{special}->{node} from springing into existance
3631
- my $s = $attributes->{special}; $s = $s->{$class} if exists $s->{$class};
3632
- my $entry = $s->{$name} ||
3633
- $attributes->{all}->{$name} ||
3634
- $attributes->{$base_class}->{$name};
3635
-
3636
- # create a fake entry for custom attributes
3637
- $entry = [ '', undef, '', '', ATTR_STRING, '' ]
3638
- if $name =~ $qr_custom_attribute;
3639
-
3640
- # Didn't found an entry:
3641
- return $self->_unknown_attribute($name,$class) unless ref($entry);
3642
-
3643
- my $type = $entry->[ ATTR_TYPE_SLOT ] || ATTR_STRING;
3644
-
3645
- my $val;
3646
-
3647
- if ($three_arg == 0)
3648
- {
3649
- ###########################################################################
3650
- # Check the object directly first
3651
- my $a = $self->{att};
3652
- if (exists $a->{graph})
3653
- {
3654
- # for graphs, look directly in the class to save time:
3655
- $val = $a->{graph}->{$name}
3656
- if exists $a->{graph}->{$name};
3657
- }
3658
- else
3659
- {
3660
- $val = $a->{$name} if exists $a->{$name};
3661
- }
3662
-
3663
- # For "background", and objects that are in a group, we inherit "fill":
3664
- if ($name eq 'background' && $val && $val eq 'inherit')
3665
- {
3666
- my $parent = $self->parent();
3667
- $val = $parent->color_attribute('fill') if $parent && $parent != $self;
3668
- }
3669
-
3670
- # XXX BENCHMARK THIS
3671
- return $val if defined $val &&
3672
- # no inheritance ("inherit" is just a normal string value)
3673
- ($type >= ATTR_NO_INHERIT ||
3674
- # no inheritance since value is something else like "red"
3675
- $val ne 'inherit' ||
3676
- # for graphs, there is nothing to inherit from
3677
- $class eq 'graph');
3678
- }
3679
-
3680
- # $val not defined, or 'inherit'
3681
-
3682
- ###########################################################################
3683
- # Check the classes now
3684
-
3685
- # print STDERR "# Called self->attribute($class,$name) (#2)\n";
3686
-
3687
- # we try them in this order:
3688
- # node.subclass, node, graph
3689
-
3690
- # print STDERR "# $self->{name} class=$class ", join(" ", caller),"\n" if $name eq 'align';
3691
-
3692
- my @tries = ();
3693
- # skip "node.foo" if value is 'inherit'
3694
- push @tries, $class unless defined $val;
3695
- push @tries, $base_class if $class =~ /\./;
3696
- push @tries, 'graph' unless @tries && $tries[-1] eq 'graph';
3697
-
3698
- # If not part of a graph, we cannot have class attributes, but
3699
- # we still can find default attributes. So fake a "graph":
3700
- my $g = $self->{graph}; # for objects in a graph
3701
- $g = { att => {} } unless ref($g); # for objects not in a graph
3702
-
3703
- # XXX TODO should not happen
3704
- $g = $self if $self->{class} eq 'graph'; # for the graph itself
3705
-
3706
- $val = undef;
3707
- TRY:
3708
- for my $try (@tries)
3709
- {
3710
- # print STDERR "# Trying class $try for attribute $name\n" if $name eq 'align';
3711
-
3712
- my $att = $g->{att}->{$try};
3713
-
3714
- $val = $att->{$name} if exists $att->{$name};
3715
-
3716
- # value was not defined, so get the default value (but not for subclasses!)
3717
- if (!defined $val)
3718
- {
3719
- my $def = $entry->[ ATTR_DEFAULT_SLOT ]; $val = $def;
3720
-
3721
- # "node.subclass" gets the default from "node", 'edge' from 'default':
3722
- # " { default => 'foo', 'node.anon' => 'none', node => 'solid' }":
3723
- if (ref $def)
3724
- {
3725
- $val = $def->{$try};
3726
- if (!defined $val && $try =~ /\./)
3727
- {
3728
- my $base = $try; $base =~ s/\..*//;
3729
- $val = $def->{$base};
3730
- }
3731
- # if this is not a subclass, get the default value
3732
- next TRY if !defined $val && $try =~ /\./;
3733
-
3734
- $val = $def->{default} unless defined $val;
3735
- }
3736
- }
3737
- # $val must now be defined, because default value must exist.
3738
-
3739
- # print STDERR "# Found '$val' for $try ($class)\n" if $name eq 'color';
3740
-
3741
- if ($name ne 'label')
3742
- {
3743
- $self->warn("Uninitialized default for attribute '$name' on class '$try'\n")
3744
- unless defined $val;
3745
- }
3746
-
3747
- return $val if $type >= ATTR_NO_INHERIT;
3748
-
3749
- # got some value other than inherit or already at top of tree:
3750
- last if defined $val && ($val ne 'inherit' || $try eq 'graph');
3751
-
3752
- # try next class in inheritance tree
3753
- $val = undef;
3754
- }
3755
-
3756
- # For "background", and objects that are in a group, we inherit "fill":
3757
- if ($name eq 'background' && $val && $val eq 'inherit')
3758
- {
3759
- my $parent = $self->parent();
3760
- $val = $parent->color_attribute('fill') if $parent && $parent != $self;
3761
- }
3762
-
3763
- # If we fell through here, $val is 'inherit' for graph. That happens
3764
- # for instance for 'background':
3765
- $val;
3766
- }
3767
-
3768
- sub unquote_attribute
3769
- {
3770
- # The parser leaves quotes and escapes in the attribute, these things
3771
- # are only removed upon storing the attribute at the object/class.
3772
- # Return the attribute unquoted (remove quotes on labels, links etc).
3773
- my ($self,$class,$name,$val) = @_;
3774
-
3775
- # clean quoted strings
3776
- # XXX TODO
3777
- # $val =~ s/^["'](.*[^\\])["']\z/$1/;
3778
- $val =~ s/^["'](.*)["']\z/$1/;
3779
-
3780
- $val =~ s/\\([#"';\\])/$1/g; # reverse backslashed chars
3781
-
3782
- # remove any %00-%1f, %7f and high-bit chars to avoid exploits and problems
3783
- $val =~ s/%[^2-7][a-fA-F0-9]|%7f//g;
3784
-
3785
- # decode %XX entities
3786
- $val =~ s/%([2-7][a-fA-F0-9])/sprintf("%c",hex($1))/eg;
3787
-
3788
- $val;
3789
- }
3790
-
3791
- sub valid_attribute
3792
- {
3793
- # Only for compatibility, use validate_attribute()!
3794
-
3795
- # Check that an name/value pair is an valid attribute, returns:
3796
- # scalar value: valid, new attribute
3797
- # undef: not valid
3798
- # []: unknown attribute (might also warn)
3799
- my ($self, $name, $value, $class) = @_;
3800
-
3801
- my ($error,$newname,$v) = $self->validate_attribute($name,$value,$class);
3802
-
3803
- return [] if defined $error && $error == 1;
3804
- return undef if defined $error && $error == 2;
3805
- $v;
3806
- }
3807
-
3808
- sub validate_attribute
3809
- {
3810
- # Check that an name/value pair is an valid attribute, returns:
3811
- # $error, $newname, @values
3812
-
3813
- # A possible new name is in $newname, this is f.i. used to convert
3814
- # "font-size" # to "fontsize".
3815
-
3816
- # Upon errors, $error contains the error code:
3817
- # undef: all went well
3818
- # 1 unknown attribute name
3819
- # 2 invalid attribute value
3820
- # 4 found multiple attributes, but these aren't
3821
- # allowed at this place
3822
-
3823
- my ($self, $name, $value, $class, $no_multiples) = @_;
3824
-
3825
- $self->error("Got reference $value as value, but expected scalar") if ref($value);
3826
- $self->error("Got reference $name as name, but expected scalar") if ref($name);
3827
-
3828
- # "x-foo-bar" is a custom attribute, so allow it always. The name must
3829
- # consist only of letters and hyphens, and end in a letter. Hyphens
3830
- # must be separated by letters.
3831
- return (undef, $name, $value) if $name =~ $qr_custom_attribute;
3832
-
3833
- $class = 'all' unless defined $class;
3834
- $class =~ s/\..*\z//; # remove subclasses
3835
-
3836
- # Remap alias names without "-" to their hyphenated version:
3837
- $name = $att_aliases->{$name} if exists $att_aliases->{$name};
3838
-
3839
- # prevent ->{special}->{node} from springing into existance
3840
- my $s = $attributes->{special}; $s = $s->{$class} if exists $s->{$class};
3841
-
3842
- my $entry = $s->{$name} ||
3843
- $attributes->{all}->{$name} || $attributes->{$class}->{$name};
3844
-
3845
- # Didn't found an entry:
3846
- return (1,undef,$self->_unknown_attribute($name,$class)) unless ref($entry);
3847
-
3848
- my $check = $entry->[ATTR_MATCH_SLOT];
3849
- my $type = $entry->[ATTR_TYPE_SLOT] || ATTR_STRING;
3850
-
3851
- $check = '_color' if $type == ATTR_COLOR;
3852
- $check = '_angle' if $type == ATTR_ANGLE;
3853
- $check = '_uint' if $type == ATTR_UINT;
3854
-
3855
- my @values = ($value);
3856
-
3857
- # split on "|", but not on "\|"
3858
- # XXX TODO:
3859
- # This will not work in case of mixed " $i \|\| 0| $a = 1;"
3860
-
3861
- # When special attributes are set, we are parsing Graphviz, and do
3862
- # not allow/use multiple attributes. So skip the split.
3863
- if (keys %{$attributes->{special}} == 0)
3864
- {
3865
- @values = split (/\s*\|\s*/, $value, -1) if $value =~ /(^|[^\\])\|/;
3866
- }
3867
-
3868
- my $multiples = 0; $multiples = 1 if @values > 1;
3869
- return (4) if $no_multiples && $multiples; # | and no multiples => error
3870
-
3871
- # check each part on it's own
3872
- my @rc;
3873
- for my $v (@values)
3874
- {
3875
- # don't check empty parts for being valid
3876
- push @rc, undef and next if $multiples && $v eq '';
3877
-
3878
- if (defined $check && !ref($check))
3879
- {
3880
- no strict 'refs';
3881
- my $checked = $self->$check($v, $name);
3882
- if (!defined $checked)
3883
- {
3884
- $self->error("Error in attribute: '$v' is not a valid $name for a $class");
3885
- return (2);
3886
- }
3887
- push @rc, $checked;
3888
- }
3889
- elsif ($check)
3890
- {
3891
- if (ref($check) eq 'ARRAY')
3892
- {
3893
- # build a regexp from the list of words
3894
- my $list = 'qr/^(' . join ('|', @$check) . ')\z/;';
3895
- $entry->[1] = eval($list);
3896
- $check = $entry->[1];
3897
- }
3898
- if ($v !~ $check) # invalid?
3899
- {
3900
- $self->error("Error in attribute: '$v' is not a valid $name for a $class");
3901
- return (2);
3902
- }
3903
-
3904
- push @rc, $v; # valid
3905
- }
3906
- # entry found, but no specific check => anything goes as value
3907
- else { push @rc, $v; }
3908
-
3909
- # "ClAss" => "class" for LCTEXT entries
3910
- $rc[-1] = lc($rc[-1]) if $type == ATTR_LCTEXT;
3911
- }
3912
-
3913
- # only one value ('green')
3914
- return (undef, $name, $rc[0]) unless $multiples;
3915
-
3916
- # multiple values ('green|red')
3917
- (undef, $name, \@rc);
3918
- }
3919
-
3920
- ###########################################################################
3921
- ###########################################################################
3922
-
3923
- sub _remap_attributes
3924
- {
3925
- # Take a hash with:
3926
- # {
3927
- # class => {
3928
- # color => 'red'
3929
- # }
3930
- # }
3931
- # and remap it according to the given remap hash (similiar structured).
3932
- # Also encode/quote the value. Suppresses default attributes.
3933
- my ($self, $object, $att, $remap, $noquote, $encode, $color_remap ) = @_;
3934
-
3935
- my $out = {};
3936
-
3937
- my $class = $object || 'node';
3938
- $class = $object->{class} || 'graph' if ref($object);
3939
- $class =~ s/\..*//; # remove subclass
3940
-
3941
- my $r = $remap->{$class};
3942
- my $ra = $remap->{all};
3943
- my $ral = $remap->{always};
3944
- my $x = $remap->{x};
3945
-
3946
- # This loop does also handle the individual "bordercolor" attributes.
3947
- # If the output should contain only "border", but not "bordercolor", then
3948
- # the caller must filter them out.
3949
-
3950
- # do these attributes
3951
- my @keys = keys %$att;
3952
-
3953
- my $color_scheme = 'w3c';
3954
- $color_scheme = $object->attribute('colorscheme') if ref($object);
3955
- $color_scheme = $self->get_attribute($object,'colorscheme')
3956
- if defined $object && !ref($object);
3957
-
3958
- $color_scheme = $self->get_attribute('graph','colorscheme')
3959
- if defined $color_scheme && $color_scheme eq 'inherit';
3960
-
3961
- for my $atr (@keys)
3962
- {
3963
- my $val = $att->{$atr};
3964
-
3965
- # Only for objects (not for classes like "node"), and not if
3966
- # always says we need to always call the CODE handler:
3967
-
3968
- if (!ref($object) && !exists $ral->{$atr})
3969
- {
3970
- # attribute not defined
3971
- next if !defined $val || $val eq '' ||
3972
- # or $remap says we should suppress it
3973
- (exists $r->{$atr} && !defined $r->{$atr}) ||
3974
- (exists $ra->{$atr} && !defined $ra->{$atr});
3975
- }
3976
-
3977
- my $entry = $attributes->{all}->{$atr} || $attributes->{$class}->{$atr};
3978
-
3979
- if ($color_remap && defined $entry && defined $val)
3980
- {
3981
- # look up whether attribute is a color
3982
- # if yes, convert to hex
3983
- $val = $self->color_as_hex($val,$color_scheme)
3984
- if ($entry->[ ATTR_TYPE_SLOT ]||ATTR_STRING) == ATTR_COLOR;
3985
- }
3986
-
3987
- my $temp = { $atr => $val };
3988
-
3989
- # see if there is a handler for custom attributes
3990
- if (exists $r->{$atr} || exists $ra->{$atr} || (defined $x && $atr =~ /^x-/))
3991
- {
3992
- my $rc = $r->{$atr}; $rc = $ra->{$atr} unless defined $rc;
3993
- $rc = $x unless defined $rc;
3994
-
3995
- # if given a code ref, call it to remap name and/or value
3996
- if (ref($rc) eq 'CODE')
3997
- {
3998
- my @rc = &{$rc}($self,$atr,$val,$object);
3999
- $temp = {};
4000
- while (@rc)
4001
- {
4002
- my $a = shift @rc; my $v = shift @rc;
4003
- $temp->{ $a } = $v if defined $a && defined $v;
4004
- }
4005
- }
4006
- else
4007
- {
4008
- # otherwise, rename the attribute name if nec.
4009
- $temp = { };
4010
- $temp = { $rc => $val } if defined $val && defined $rc;
4011
- }
4012
- }
4013
-
4014
- for my $at (keys %$temp)
4015
- {
4016
- my $v = $temp->{$at};
4017
-
4018
- next if !defined $at || !defined $v || $v eq '';
4019
-
4020
- # encode critical characters (including "), but only if the value actually
4021
- # contains anything else than '%' (so rgb(10%,0,0) stays as it is)
4022
-
4023
- $v =~ s/([;"%\x00-\x1f])/sprintf("%%%02x",ord($1))/eg
4024
- if $encode && $v =~ /[;"\x00-\x1f]/;
4025
- # quote if nec.
4026
- $v = '"' . $v . '"' unless $noquote;
4027
-
4028
- $out->{$at} = $v;
4029
- }
4030
- }
4031
-
4032
- $out;
4033
- }
4034
-
4035
- sub raw_attributes
4036
- {
4037
- # return all set attributes on this object (graph/node/group/edge) as
4038
- # an anonymous hash ref
4039
- my $self = shift;
4040
-
4041
- my $class = $self->{class} || 'graph';
4042
-
4043
- my $att = $self->{att};
4044
- $att = $self->{att}->{graph} if $class eq 'graph';
4045
-
4046
- my $g = $self->{graph} || $self;
4047
-
4048
- my $out = {};
4049
- if (!$g->{strict})
4050
- {
4051
- for my $name (keys %$att)
4052
- {
4053
- my $val = $att->{$name};
4054
- next unless defined $val; # set to undef?
4055
-
4056
- $out->{$name} = $val;
4057
- }
4058
- return $out;
4059
- }
4060
-
4061
- my $base_class = $class; $base_class =~ s/\..*//;
4062
- for my $name (keys %$att)
4063
- {
4064
- my $val = $att->{$name};
4065
- next unless defined $val; # set to undef?
4066
-
4067
- $out->{$name} = $val;
4068
-
4069
- next unless $val eq 'inherit';
4070
-
4071
- # prevent ->{special}->{node} from springing into existance
4072
- my $s = $attributes->{special}; $s = $s->{$class} if exists $s->{$class};
4073
- my $entry = $s->{$name} ||
4074
- $attributes->{all}->{$name} ||
4075
- $attributes->{$base_class}->{$name};
4076
-
4077
- # Didn't found an entry:
4078
- return $self->_unknown_attribute($name,$class) unless ref($entry);
4079
-
4080
- my $type = $entry->[ ATTR_TYPE_SLOT ] || ATTR_STRING;
4081
-
4082
- # need to inherit value?
4083
- $out->{$name} = $self->attribute($name) if $type < ATTR_NO_INHERIT;
4084
- }
4085
-
4086
- $out;
4087
- }
4088
-
4089
- sub get_attributes
4090
- {
4091
- # Return all effective attributes on this object (graph/node/group/edge) as
4092
- # an anonymous hash ref. This respects inheritance and default values.
4093
- # Does not return custom attributes, see get_custom_attributes().
4094
- my $self = shift;
4095
-
4096
- $self->error("get_attributes() doesn't take arguments") if @_ > 0;
4097
-
4098
- my $att = {};
4099
- my $class = $self->main_class();
4100
-
4101
- # f.i. "all", "node"
4102
- for my $type ('all', $class)
4103
- {
4104
- for my $a (keys %{$attributes->{$type}})
4105
- {
4106
- my $val = $self->attribute($a); # respect inheritance
4107
- $att->{$a} = $val if defined $val;
4108
- }
4109
- }
4110
-
4111
- $att;
4112
- }
4113
-
4114
- package Graph::Easy::Node;
4115
-
4116
- BEGIN
4117
- {
4118
- *custom_attributes = \&get_custom_attributes;
4119
- }
4120
-
4121
- sub get_custom_attributes
4122
- {
4123
- # Return all custom attributes on this object (graph/node/group/edge) as
4124
- # an anonymous hash ref.
4125
- my $self = shift;
4126
-
4127
- $self->error("get_custom_attributes() doesn't take arguments") if @_ > 0;
4128
-
4129
- my $att = {};
4130
-
4131
- for my $key (keys %{$self->{att}})
4132
- {
4133
- $att->{$key} = $self->{att}->{$key};
4134
- }
4135
-
4136
- $att;
4137
- }
4138
-
4139
- 1;
4140
- __END__
4141
-
4142
- =head1 NAME
4143
-
4144
- Graph::Easy::Attributes - Define and check attributes for Graph::Easy
4145
-
4146
- =head1 SYNOPSIS
4147
-
4148
- use Graph::Easy;
4149
-
4150
- my $graph = Graph::Easy->new();
4151
-
4152
- my $hexred = Graph::Easy->color_as_hex( 'red' );
4153
- my ($name, $value) = $graph->valid_attribute( 'color', 'red', 'graph' );
4154
- print "$name => $value\n" if !ref($value);
4155
-
4156
- =head1 DESCRIPTION
4157
-
4158
- C<Graph::Easy::Attributes> contains the definitions of valid attribute names
4159
- and values for L<Graph::Easy|Graph::Easy>. It is used by both the parser
4160
- and by Graph::Easy to check attributes for being valid and well-formed.
4161
-
4162
- There should be no need to use this module directly.
4163
-
4164
- For a complete list of attributes and their possible values, please see
4165
- L<Graph::Easy::Manual>.
4166
-
4167
- =head1 EXPORT
4168
-
4169
- Exports nothing.
4170
-
4171
- =head1 SEE ALSO
4172
-
4173
- L<Graph::Easy>.
4174
-
4175
- =head1 AUTHOR
4176
-
4177
- Copyright (C) 2004 - 2008 by Tels L<http://bloodgate.com>
4178
-
4179
- See the LICENSE file for information.
4180
-
4181
- =cut