@ca-plant-list/ca-plant-list 0.4.31 → 0.4.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/data/synonyms.csv CHANGED
@@ -686,6 +686,7 @@ Erigeron peregrinus var. callianthemus,Erigeron glacialis var. glacialis
686
686
  Eriocoma lemmonii subsp. lemmonii,Stipa lemmonii var. lemmonii,INAT
687
687
  Eriogonella membranacea,Chorizanthe membranacea
688
688
  Eriogonum acetoselloides,Eriogonum gracile var. gracile
689
+ Eriogonum arachnoideum,Eriogonum latifolium
689
690
  Eriogonum auriculatum,Eriogonum nudum var. auriculatum
690
691
  Eriogonum caninum,Eriogonum luteolum var. caninum
691
692
  Eriogonum curvatum,Eriogonum wrightii var. subscaposum
@@ -706,6 +707,7 @@ Eriogonum lobbii var. minus,Eriogonum lobbii
706
707
  Eriogonum marifolium var. incanum,Eriogonum incanum
707
708
  Eriogonum nivale,Eriogonum ovalifolium var. nivale
708
709
  Eriogonum nudum subsp. pauciflorum,Eriogonum nudum var. pauciflorum
710
+ Eriogonum oblongifolium,Eriogonum latifolium
709
711
  Eriogonum polifolium,Eriogonum fasciculatum var. polifolium
710
712
  Eriogonum polyanthum var. bahiiforme,Eriogonum umbellatum var. bahiiforme
711
713
  Eriogonum revolutum,Eriogonum fasciculatum var. polifolium
@@ -1096,6 +1098,7 @@ Linum micranthum,Hesperolinon micranthum
1096
1098
  Linum perenne subsp. lewisii,Linum lewisii var. lewisii
1097
1099
  Lippia lanceolata,Phyla lanceolata
1098
1100
  Lithophragma affine subsp. mixtum,Lithophragma affine
1101
+ Lithophragma parviflorum,Lithophragma parviflorum var. parviflorum,INAT
1099
1102
  Lithophragma scabrella,Lithophragma bolanderi
1100
1103
  Lithophragma tripartitum,Lithophragma affine
1101
1104
  Lolium arundinaceum,Festuca arundinacea,INAT
@@ -1152,7 +1155,6 @@ Lupinus congdonii,Lupinus bicolor
1152
1155
  Lupinus densiflorus,Lupinus microcarpus var. densiflorus
1153
1156
  Lupinus densiflorus var. aureus,Lupinus microcarpus var. densiflorus
1154
1157
  Lupinus densiflorus var. austrocollium,Lupinus microcarpus var. microcarpus
1155
- Lupinus densiflorus var. densiflorus,Lupinus microcarpus var. densiflorus,INAT
1156
1158
  Lupinus densiflorus var. palustris,Lupinus microcarpus var. microcarpus
1157
1159
  Lupinus densiflorus var. persecundus,Lupinus microcarpus var. microcarpus
1158
1160
  Lupinus nanus subsp. apricus,Lupinus nanus
@@ -1689,6 +1691,7 @@ Quercus lobata f. rarita,Quercus lobata
1689
1691
  Quercus lobata var. lobata,Quercus lobata
1690
1692
  Quercus lobata var. turbinata,Quercus lobata
1691
1693
  Quercus lobata var. walteri,Quercus lobata
1694
+ Ranunculus aquatilis,Ranunculus aquatilis var. aquatilis,INAT
1692
1695
  Ranunculus aquatilis var. capillaceus,Ranunculus aquatilis var. diffusus
1693
1696
  Ranunculus aquatilis var. harrisii,Ranunculus aquatilis var. diffusus
1694
1697
  Ranunculus aquatilis var. hispidulus,Ranunculus aquatilis var. aquatilis
package/data/taxa.csv CHANGED
@@ -37,11 +37,12 @@ Aegilops triuncialis,barbed goatgrass,X,11997,107,60272,134011,true
37
37
  Aesculus californica,California buckeye,N,12026,111,53348,9383,,California Buckeye,,white
38
38
  Ageratina adenophora,,X,735,117,64114,201878,true
39
39
  Agoseris apargioides var. apargioides,,N,6310,122,58797,201889,true,Coast Dandelion
40
- Agoseris grandiflora var. grandiflora,perennial,N,79217,10490,80331,201900,true,Giant Mountain Dandelion,,yellow,4,7
41
- Agoseris heterophylla var. cryptopleura,annual,N,6324,10758,80333,206485,true,,,yellow,5,6
42
- Agoseris heterophylla var. heterophylla,,N,6323,9654,56859,206486,true
40
+ Agoseris grandiflora var. grandiflora,big mountain dandelion,N,79217,10490,80331,201900,true,Giant Mountain Dandelion,perennial,yellow,4,7
41
+ Agoseris heterophylla var. cryptopleura,mountain dandelion,N,6324,10758,80333,206485,true,,annual,yellow,5,6
42
+ Agoseris heterophylla var. heterophylla,annual false dandelion,N,6323,9654,56859,206486,true,,annual,yellow,5,6
43
43
  Agoseris heterophylla,,N,794,132,56856,201901,true,Annual Agoseris
44
- Agoseris retrorsa,,N,797,133,57908,201902,true,Spearleaf Agoseris
44
+ Agoseris hirsuta,Coast Range agoseris,N,777,10491,61169,206487,true,Coast Range Agoseris,perennial,yellow,4,6
45
+ Agoseris retrorsa,spearleaf agoseris,N,797,133,57908,201902,true,Spearleaf Agoseris,perennial,yellow,4,8
45
46
  Agrostis avenacea,blown grass,X,12268,138,288066,134238,Lachnagrostis filiformis
46
47
  Agrostis capillaris,colonial bent,X,12276,140,75312,134268,true
47
48
  Agrostis exarata,spike redtop,N,12284,143,59088,134320,true,Spike Bentgrass
@@ -237,7 +238,7 @@ Brickellia californica,California brickelbush,N,1794,1152,58803,202493,true,Bric
237
238
  Briza maxima,quaking grass,X,16135,1165,57157,136989,true
238
239
  Briza minor,little quaking grass,X,16137,1166,57162,136993,true
239
240
  Brodiaea elegans subsp. elegans,harvest brodiaea,N,49461,1175,57127,202520,true,Harvest Brodiaea,corm,purple,4,8
240
- Brodiaea terrestris subsp. terrestris,,N,49464,1188,59081,202533,true,Dwarf Brodiaea,corm
241
+ Brodiaea terrestris subsp. terrestris,,N,49464,1188,59081,202533,true,Dwarf Brodiaea,corm,purple,4,7
241
242
  Bromus arenarius,Australian chess,X,16216,1191,58368,137101,true
242
243
  Bromus berteroanus,Chilean chess,X,16219,9740,75897,137110,true
243
244
  Bromus catharticus var. catharticus,rescue grass,X,85279,11433,80494,169088,true
@@ -275,9 +276,9 @@ Callitriche marginata,water-starwort,N,16692,1259,58093,64128,true,Winged Water
275
276
  Callitriche trochlearis,,N,16702,1261,69994,64137,true,Effluent Water-starwort
276
277
  Calochortus albus,white globe lily,N,16710,1264,51315,202570,true,White Globe Lily,,white,4,6
277
278
  Calochortus argillosus,clay mariposa lily,N,76542,1268,64330,202576,true,Clay Mariposa Lily,bulb,"white,pink",4,6
278
- Calochortus clavatus var. pallidus,bulb,N,55455,1275,58360,202583,true,Pale Yellow Mariposa
279
- Calochortus invenustus,bulb,N,16733,1284,64432,202590,true,Plain Mariposa Lily
280
- Calochortus leichtlinii,bulb,N,16735,1288,52542,202594,true,Leichtlin's Mariposa Lily
279
+ Calochortus clavatus var. pallidus,,N,55455,1275,58360,202583,true,Pale Yellow Mariposa
280
+ Calochortus invenustus,,N,16733,1284,64432,202590,true,Plain Mariposa Lily
281
+ Calochortus leichtlinii,,N,16735,1288,52542,202594,true,Leichtlin's Mariposa Lily
281
282
  Calochortus luteus,yellow mariposa lily,N,16737,1290,51077,202595,true,Yellow Mariposa Lily,bulb,yellow,4,6
282
283
  Calochortus pulchellus,Mt. Diablo fairy lantern,N,16755,1303,47326,202609,true,Mt. Diablo Fairy Lantern,bulb,,,,50,1B.2,,,S2,G2
283
284
  Calochortus splendens,,N,16759,1306,58361,202611,true,Splendid Mariposa Lily,bulb
@@ -307,7 +308,7 @@ Camissoniopsis intermedia,,N,89203,11455,75982,12189,true,Intermediate Suncup
307
308
  Camissoniopsis micrantha,,N,89206,11458,75985,12192,true,Small Flowered Evening Primrose
308
309
  Capsella bursa-pastoris,shepherd's purse,X,17109,1472,56121,12296,true
309
310
  Cardamine californica,"milkmaids,tooth wort",N,76456,1479,49651,12325,true,Milk Maids
310
- Cardamine hirsuta,,X,17158,1486,55829,12347,true
311
+ Cardamine hirsuta,hairy bittercress,X,17158,1486,55829,12347,true
311
312
  Cardamine oligosperma,,N,17171,1493,52981,12369,true,Little Western Bittercress
312
313
  Carduus pycnocephalus subsp. pycnocephalus,Italian thistle,X,82221,11464,79672,202704,true
313
314
  Carduus tenuiflorus,,X,1902,1505,53007,202705,true
@@ -364,7 +365,7 @@ Ceanothus thyrsiflorus,blue blossom,N,18501,1830,56617,12790,true,Blueblossom Ce
364
365
  Centaurea calcitrapa,purple star-thistle,X,1922,1845,56865,202776,true
365
366
  Centaurea cyanus,"bachelor's button,cornflower",X,1925,1846,933404,202778,true
366
367
  Centaurea iberica,Iberian starthistle,X,1931,1849,76212,206620,true
367
- Centaurea melitensis,"tocalote,Maltese start-thistle",X,1934,1851,57922,202785,true
368
+ Centaurea melitensis,"tocalote,Maltese star-thistle",X,1934,1851,57922,202785,true
368
369
  Centaurea solstitialis,yellow star-thistle,X,1946,1853,52588,202793,true
369
370
  Centranthus ruber,red valerian,X,18595,1864,57283,202799
370
371
  Centromadia fitchii,Fitch's spikeweed,N,77593,10809,58804,202801,true,Fitch Spikeweed
@@ -443,7 +444,7 @@ Claytonia exigua subsp. glauca,,N,76949,2233,57229,127855,true,Serpentine Spring
443
444
  Claytonia gypsophiloides,candy stripers,N,19620,2234,55344,112597,true,Gypsum Springbeauty,annual,pink,3,5
444
445
  Claytonia parviflora subsp. parviflora,,N,74695,2242,58296,127861,true,Utah Miner's Lettuce,"annual,perennial",white,3,6
445
446
  Claytonia perfoliata subsp. mexicana,,N,76956,2245,53004,127866,true,Southern Miner's Lettuce,annual,white,2,4
446
- Claytonia perfoliata subsp. perfoliata,Miner's lettuce,N,49921,2246,53002,127867,true,Miner's Lettuce,annual,white,1,5
447
+ Claytonia perfoliata subsp. perfoliata,miner's lettuce,N,49921,2246,53002,127867,true,Miner's Lettuce,annual,white,1,5
447
448
  Claytonia rubra subsp. depressa,red stem spring beauty,N,76957,2248,79751,127869,true,Miner's Lettuce,annual,white,2,4
448
449
  Clematis lasiantha,pipestems,N,19682,2254,49876,13749,true,Chaparral Clematis,,white,1,6
449
450
  Clematis ligusticifolia,virgin's bower,N,19683,2255,58996,13750,true,Virgin's Bower,,white,6,9
@@ -701,6 +702,7 @@ Eriogonum fasciculatum var. polifolium,,N,58546,3247,58272,129983,true,Interior
701
702
  Eriogonum gracile var. gracile,slender buckwheat,N,58563,3257,58982,129999,true,Slender Woolly Wild Buckwheat
702
703
  Eriogonum incanum,frosted buckwheat,N,24809,3279,62680,114044,true,Frosted Wild Buckwheat,perennial,yellow,6,9
703
704
  Eriogonum inerme var. inerme,unarmed buckwheat,N,58586,9110,80799,130026,true,Unarmed Wild Buckwheat
705
+ Eriogonum latifolium,seaside wild buckwheat,N,24832,3293,57211,114060,true,Coast Buckwheat,perennial,"white,pink",1,12
704
706
  Eriogonum lobbii,granite buckwheat,N,24839,9935,77005,114067,true,Lobb's Buckwheat,perennial,"white,pink",6,8
705
707
  Eriogonum luteolum var. caninum,Tiburon buckwheat,N,58623,3297,61205,130067,true,Tiburon Buckwheat,,,,,733,1B.2,,,S2,G5T2
706
708
  Eriogonum luteolum var. luteolum,,N,58624,3298,64226,130068,true,Golden-carpet Wild Buckwheat
@@ -835,7 +837,7 @@ Geranium molle,cranes-bill geranium,X,26729,3800,53076,22359
835
837
  Geranium potentilloides,,X,26735,3802,77258,22368
836
838
  Geranium purpureum,little robin,X,77514,8594,57643,22370
837
839
  Geranium robertianum,,X,26742,3806,55925,22376
838
- Geranium rotundifolium,,X,26743,3808,77261,22377
840
+ Geranium rotundifolium,round-leaved crane's-bill,X,26743,3808,77261,22377
839
841
  Gilia achilleifolia subsp. achilleifolia,,N,50744,3813,51101,95568,,California Gilia
840
842
  Gilia achilleifolia subsp. multicaulis,,N,50745,3814,51102,95570,,California Gilia
841
843
  Gilia capitata subsp. capitata,,N,50764,3834,57798,95588,,Bluehead Gilia
@@ -894,7 +896,7 @@ Heterotheca grandiflora,telegraph weed,N,3419,4142,58831,204286,true,Telegraph W
894
896
  Heterotheca oregona var. rudis,Oregon goldenaster,N,7614,4146,,206910,true
895
897
  Heterotheca oregona var. scaberrima,goldenaster,N,7616,4147,80937,204289,true
896
898
  Heterotheca sessiliflora subsp. bolanderi,Bolander's goldenaster,N,74443,4151,61170,204291,true,Bolander's Goldenaster
897
- Heterotheca sessiliflora subsp. echioides,,N,74445,4152,58834,204292,true,Bristly Goldenaster
899
+ Heterotheca sessiliflora subsp. echioides,bristly goldenaster,N,74445,4152,58834,204292,true,Bristly Goldenaster
898
900
  Heuchera micrantha,alumroot,N,28126,4171,51274,22981,true,Crevice Alumroot
899
901
  Hibiscus lasiocarpos var. occidentalis,rose-mallow,N,91751,11194,80940,266649,,Rose Mallow,,,,,906,1B.2,,,S3,G5T3
900
902
  Hieracium albiflorum,white hawkweed,N,3471,4184,63937,204303,true,White Hawkweed
@@ -920,7 +922,7 @@ Hordeum murinum subsp. leporinum,,X,50971,4227,52795,204330,true
920
922
  Hordeum murinum subsp. murinum,,X,50972,4228,63333,167373,true
921
923
  Horkelia californica var. californica,California horkelia,N,81857,11731,237030,48514,true,California Horkelia
922
924
  Horkelia californica var. elata,tall horkelia,N,81856,11732,80945,48515,true,California Honeydew
923
- Horkelia californica var. frondosa,leafy horkelia,N,81858,11733,,48516,true,California Horkelia
925
+ Horkelia californica var. frondosa,leafy horkelia,N,81858,11733,1629357,48516,true,California Horkelia
924
926
  Horkelia cuneata var. sericea,Kellogg's horkelia,N,81861,11738,80951,48524,true,Kellogg's Horkelia,,,,,910,1B.1,,,S1?,G4T1?
925
927
  Hornungia procumbens,,X,81333,11748,77452,23250,true
926
928
  Hosackia crassifolia var. crassifolia,,N,91757,11750,80960,48541,,Big Deervetch
@@ -1082,17 +1084,17 @@ Lithophragma affine,woodland star,N,31236,4922,50803,24525,true,San Francisco Wo
1082
1084
  Lithophragma bolanderi,,N,31238,4923,77787,24527,true,Bolander's Woodland Star,perennial,white,2,7
1083
1085
  Lithophragma cymbalaria,,N,31241,4925,58323,24531,true,Mission Woodland Star,perennial,white,3,5
1084
1086
  Lithophragma heterophyllum,hill starflower,N,31244,4927,53124,24533,true,Hillside Woodland Star,perennial,white,2,6
1085
- Lithophragma parviflorum var. parviflorum,,N,60952,4930,81027,48936,Lithophragma parviflorum,Smallflower Woodland-star,perennial,"white,pink",3,7
1087
+ Lithophragma parviflorum var. parviflorum,,N,60952,4930,77791,48936,Lithophragma parviflorum,Smallflower Woodland-star,perennial,"white,pink",3,7
1086
1088
  Lobularia maritima,sweet alyssum,X,31347,4939,56992,24547,true
1087
1089
  Logfia filaginoides,herba impia,N,81847,10960,64254,204735,true,California Cottonrose,annual,red,2,5
1088
1090
  Logfia gallica,,X,31363,9521,56949,204736,true,,annual,"brown,yellow",3,7
1089
1091
  Lomatium californicum,chu-chu-pate,N,31389,4950,56824,204737,,California Lomatium,,yellow,4,6
1090
1092
  Lomatium caruifolium var. caruifolium,,N,61026,4953,64328,204739,,Alkali Desertparsley
1091
1093
  Lomatium caruifolium var. denticulatum,,N,61027,4954,60123,204740
1092
- Lomatium dasycarpum subsp. dasycarpum,,N,51334,4960,56829,204743,,Woolly Fruited Lomatium,,white,3,6
1093
- Lomatium macrocarpum,,N,31433,4974,56826,204754,,Bigseed Biscuitroot
1094
+ Lomatium dasycarpum subsp. dasycarpum,,N,51334,4960,56829,204743,,Woolly Fruited Lomatium,perennial,white,3,6
1095
+ Lomatium macrocarpum,,N,31433,4974,56826,204754,,Bigseed Biscuitroot,perennial,white,4,6
1094
1096
  Lomatium nudicaule,,N,31441,4983,77818,204759,,Barestem Biscuitroot
1095
- Lomatium utriculatum,,N,31473,4999,56827,204766,,Common Lomatium,,yellow,2,5
1097
+ Lomatium utriculatum,,N,31473,4999,56827,204766,,Common Lomatium,perennial,yellow,2,5
1096
1098
  Lonicera hispidula,California honeysuckle,N,31505,10075,53416,204768,,Pink Honeysuckle,,pink,5,6
1097
1099
  Lonicera interrupta,chaparral honeysuckle,N,31506,5009,60878,204770,,Chaparral Honeysuckle,,"yellow,white",4,5
1098
1100
  Lonicera involucrata var. ledebourii,black twinberry,N,61081,5012,60990,204773,,Twinberry Honeysuckle
@@ -1117,7 +1119,7 @@ Lupinus latifolius var. dudleyi,,N,76660,5161,81063,49195,,Broadleaf Lupine
1117
1119
  Lupinus latifolius var. latifolius,"broadleaf lupine,wood lupine",N,75772,5162,64242,204794,,Broad Leaf Lupine,perennial,blue,4,9
1118
1120
  Lupinus littoralis var. variicolor,,N,80538,14304,,49237
1119
1121
  Lupinus luteolus,butter lupine,N,31956,5176,77875,25020,,Pale Yellow Lupine
1120
- Lupinus microcarpus var. densiflorus,,N,76668,5184,241537,49248,,Dense Flowered Platycarpos,annual,"yellow,white",4,6
1122
+ Lupinus microcarpus var. densiflorus,,N,76668,5184,57058,49248,,Dense Flowered Platycarpos,annual,"yellow,white",4,6
1121
1123
  Lupinus microcarpus var. microcarpus,chick lupine,N,75776,5186,58159,204796,,Valley Lupine,annual,"pink,blue",3,6
1122
1124
  Lupinus nanus,sky lupine,N,31978,5189,50612,25068,,Sky Lupine,,blue,3,6
1123
1125
  Lupinus pachylobus,big pod lupine,N,31998,5196,50613,25085,,Big Pod Lupine
@@ -1196,8 +1198,8 @@ Mercurialis annua,annual mercury,X,33300,5450,68838,25939,true
1196
1198
  Mesembryanthemum nodiflorum,,X,33363,5461,71191,116177,true
1197
1199
  Micranthes californica,,N,91942,11841,78023,26022,true,California Saxifrage
1198
1200
  Micropus amphibolus,,N,33474,5462,78034,204946,true,Mount Diablo Cottonseed,,,,,1507,3.2,,,S3S4,G3G4
1199
- Micropus californicus var. californicus,slender cottonweed,N,7993,5464,58030,204950,true,Cottontop
1200
- Micropus californicus var. subvestitus,,N,7994,5465,81107,207081,true,Q-tips
1201
+ Micropus californicus var. californicus,slender cottonweed,N,7993,5464,58030,204950,true,Cottontop,annual,white,3,6
1202
+ Micropus californicus var. subvestitus,Q-tips,N,7994,5465,81107,207081,true,Q-tips,annual,white,4,6
1201
1203
  Microseris acuminata,,N,4146,5466,60142,204953,true,Sierra Foothill Silverpuffs
1202
1204
  Microseris bigelovii,,N,4147,5467,60977,204954,true,Coastal Silverpuffs
1203
1205
  Microseris campestris,,N,4149,5469,58031,204955,true,San Joaquin Silverpuffs
@@ -1517,7 +1519,7 @@ Quercus parvula var. shrevei,,N,76907,7005,81314,50722,,Shreve Oak
1517
1519
  Quercus wislizeni var. frutescens,,N,64776,7011,58914,50761,,Interior Live Oak
1518
1520
  Quercus wislizeni var. wislizeni,interior live oak,N,64777,7012,58915,50762,Quercus wislizeni,Interior Live Oak
1519
1521
  Rafinesquia californica,California chicory,N,4548,7013,53193,205716,true,California Plumseed
1520
- Ranunculus aquatilis var. aquatilis,,N,73500,10676,81320,50797,true
1522
+ Ranunculus aquatilis var. aquatilis,,N,73500,10676,78817,50797,true
1521
1523
  Ranunculus aquatilis var. diffusus,water buttercup,N,80687,11969,486980,50802,true,Hairleaf Water Buttercup
1522
1524
  Ranunculus californicus,California buttercup,N,40867,7032,52173,29565,true,California Buttercup,,yellow
1523
1525
  Ranunculus canus var. canus,,N,73506,11972,81324,50832,true
@@ -1534,7 +1536,7 @@ Raphanus raphanistrum,jointed charlock,X,40991,7063,55411,29701,true
1534
1536
  Raphanus sativus,wild radish,X,40992,7064,995125,29702,true
1535
1537
  Ravenella exigua,chaparral harebell,N,84837,14672,1342787,412341,,,,,,,265,1B.2,,,S2,G2
1536
1538
  Ravenella griffinii,,N,84836,14796,1342789,412342
1537
- Ravenella sharsmithiae,,N,108392,14673,1342786,208086,,,,,,,267,1B.2,,,S1S2,G1G2
1539
+ Ravenella sharsmithiae,,N,108392,14673,1342786,432222,,,,,,,267,1B.2,,,S1S2,G1G2
1538
1540
  Rhamnus alaternus,Italian buckthorn,X,81104,9447,82856,29726,true
1539
1541
  Rhamnus crocea,spiny redberry,N,41069,7075,57243,29736,true,Spiny Redberry
1540
1542
  Rhamnus ilicifolia,holly-leaf redberry,N,41070,7076,58308,29743,true,Hollyleaf Redberry
@@ -1562,6 +1564,7 @@ Rosa californica,California rose,N,41631,7179,53437,30158,true,California Wildro
1562
1564
  Rosa gymnocarpa,wood rose,N,41652,7182,53441,30212,true,Wood Rose,,pink
1563
1565
  Rosa rubiginosa,sweet-brier,X,41648,11057,78886,30313,true
1564
1566
  Rosa spithamea,ground rose,N,41696,7187,53442,30338,true,Ground Rose
1567
+ Rosa woodsii,Woods' rose,N,41704,,78887,30370,true,Woods' Rose,perennial,pink
1565
1568
  Rubus armeniacus,Himalayan blackberry,X,87465,10319,61317,30459
1566
1569
  Rubus laciniatus,cutleaf blackberry,X,42009,7195,78891,30698,true
1567
1570
  Rubus parviflorus,thimbleberry,N,42108,7200,51646,30808,true,Thimbleberry
@@ -1715,12 +1718,12 @@ Spergularia villosa,hairy sand-spurrey,X,45096,7717,60173,119423,true
1715
1718
  Spiranthes porrifolia,,N,45262,7740,50742,206062,true,Creamy Lady's Tresses
1716
1719
  Spiranthes romanzoffiana,,N,45264,7741,50743,206063,true,Irish Lady's-tresses
1717
1720
  Sporobolus airoides,alkali sacaton,N,45286,7744,60313,149026,true,Alkali Sacaton
1718
- Sporobolus alterniflorus,saltwater cordgrass,X,82872,7699,772903,148951,Spartina alterniflora
1719
- Sporobolus densiflorus,dense-flowered cordgrass,X,108405,7700,169300,148961,Spartina densiflora
1721
+ Sporobolus alterniflorus,saltwater cordgrass,X,82872,7699,772903,432224,Spartina alterniflora
1722
+ Sporobolus densiflorus,dense-flowered cordgrass,X,108405,7700,169300,432225,Spartina densiflora
1720
1723
  Sporobolus foliosus,California cordgrass,N,82873,7701,772992,208714,Spartina foliosa
1721
1724
  Sporobolus indicus,smutgrass,X,45308,7749,79187,149101,true
1722
1725
  Sporobolus niliacus,,X,82876,2440,773022,397065,Crypsis vaginiflora
1723
- Sporobolus pumilus,saltmeadow cordgrass,X,82878,7703,773004,148979,Spartina patens
1726
+ Sporobolus pumilus,saltmeadow cordgrass,X,82878,7703,773004,432226,Spartina patens
1724
1727
  Sporobolus schoenoides,swamp grass,X,82879,2439,773038,397066,Crypsis schoenoides
1725
1728
  Stachys ajugoides,hedge nettle,N,45338,7751,53295,77371,,Ajuga Hedge Nettle
1726
1729
  Stachys albens,,N,45339,7754,58192,77372,,White Hedge Nettle
@@ -1833,8 +1836,8 @@ Triphysaria eriantha subsp. eriantha,butter-and-eggs,N,53279,8129,59332,96567,tr
1833
1836
  Triphysaria pusilla,,N,47296,8133,57276,78297,true,Dwarf Owl's-clover
1834
1837
  Triphysaria versicolor subsp. faucibarbata,,N,53281,8135,60737,206269,true,Triphysaria
1835
1838
  Trisetum canescens,,N,47326,8139,1538928,150155,true,Tall False Oat
1836
- Triteleia hyacinthina,white brodiaea,N,47356,8154,57132,206275,true,White Brodiaea
1837
- Triteleia laxa,Ithuriel's spear,N,47359,8160,51085,206281,true,Ithuriel's Spear
1839
+ Triteleia hyacinthina,white brodiaea,N,47356,8154,57132,206275,true,White Brodiaea,corm,white,3,7
1840
+ Triteleia laxa,Ithuriel's spear,N,47359,8160,51085,206281,true,Ithuriel's Spear,corm,blue,3,6
1838
1841
  Triteleia peduncularis,,N,47363,8164,57133,206284,true,Long Rayed Brodiaea
1839
1842
  Tropaeolum majus,garden nasturtium,X,47408,8167,54329,34321,true
1840
1843
  Tropidocarpum capparideum,caper-fruited tropidocarpum,N,47411,8168,79456,34327,true,Caper-fruited Tropidocarpum,annual,yellow,3,4,1255,1B.1,,,S1,G1
@@ -0,0 +1 @@
1
+ Base of flower funnel-shaped.
@@ -0,0 +1 @@
1
+ Base of flower bell-shaped.
@@ -1,6 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { Files } from "../files.js";
3
3
  import { SiteGenerator } from "../sitegenerator.js";
4
+ import { XHTML } from "./xhtml.js";
4
5
 
5
6
  export class EBookSiteGenerator extends SiteGenerator {
6
7
  #pageEnd() {
@@ -21,6 +22,7 @@ export class EBookSiteGenerator extends SiteGenerator {
21
22
  "../".repeat(depth) +
22
23
  'css/main.css" rel="stylesheet" />';
23
24
  html += "</head><body>";
25
+ html += XHTML.wrap("h1", attributes.title);
24
26
  return html;
25
27
  }
26
28
 
package/lib/photo.js CHANGED
@@ -10,10 +10,10 @@ export class Photo {
10
10
  #rights;
11
11
 
12
12
  /**
13
- * @param {number} id
13
+ * @param {string} id
14
14
  * @param {string} ext
15
- * @param {import("./utils/inat-tools.js").InatLicenseCode} licenseCode
16
- * @param {string} rightsHolder
15
+ * @param {import("./utils/inat-tools.js").AllowedLicenseCode} licenseCode
16
+ * @param {string|undefined} rightsHolder
17
17
  */
18
18
  constructor(id, ext, licenseCode, rightsHolder) {
19
19
  this.#id = id;
@@ -22,7 +22,9 @@ export class Photo {
22
22
  if (licenseCode === "cc0") this.#rights = "CC0";
23
23
  else if (licenseCode === "cc-by") this.#rights = "CC BY";
24
24
  else if (licenseCode === "cc-by-nc") this.#rights = "CC BY-NC";
25
- else this.#rights = "C";
25
+ else {
26
+ throw new Error(`unexpected license code ${licenseCode}`);
27
+ }
26
28
  }
27
29
 
28
30
  /**
@@ -115,27 +115,7 @@ class Taxa {
115
115
  #loadPhotosFromFile(dataDir, filename) {
116
116
  if (!fs.existsSync(path.join(dataDir, filename))) return;
117
117
  /** @type {import("../utils/inat-tools.js").InatCsvPhoto[]} */
118
- const csvPhotos = CSV.parseFile(dataDir, filename).map((row) => {
119
- /** @type {import("../utils/inat-tools.js").InatLicenseCode} */
120
- let licenseCode = "cc-by";
121
- if (row.licenseCode === "cc-by-nc-sa") licenseCode = "cc-by-nc-sa";
122
- else if (row.licenseCode === "cc-by-nc") licenseCode = "cc-by-nc";
123
- else if (row.licenseCode === "cc-by-nc-nd")
124
- licenseCode = "cc-by-nc-nd";
125
- else if (row.licenseCode === "cc-by") licenseCode = "cc-by";
126
- else if (row.licenseCode === "cc-by-sa") licenseCode = "cc-by-sa";
127
- else if (row.licenseCode === "cc-by-nd") licenseCode = "cc-by-nd";
128
- else if (row.licenseCode === "pd") licenseCode = "pd";
129
- else if (row.licenseCode === "gdfl") licenseCode = "gdfl";
130
- else if (row.licenseCode === "cc0") licenseCode = "cc0";
131
- return {
132
- attrName: row.attrName,
133
- ext: row.ext,
134
- id: Number(row.id),
135
- licenseCode,
136
- name: row.name,
137
- };
138
- });
118
+ const csvPhotos = CSV.readFile(path.join(dataDir, filename));
139
119
  for (const csvPhoto of csvPhotos) {
140
120
  const taxon = this.getTaxon(csvPhoto.name);
141
121
  if (!taxon) {
@@ -156,8 +136,9 @@ class Taxa {
156
136
  * @param {string} dataDir
157
137
  */
158
138
  #loadInatPhotos(dataDir) {
159
- this.#loadPhotosFromFile("./data", "inatphotos.csv");
139
+ // Prefer taxon photos, as they are somewhat curated.
160
140
  this.#loadPhotosFromFile(dataDir, "inattaxonphotos.csv");
141
+ this.#loadPhotosFromFile("./data", "inatobsphotos.csv");
161
142
  this.#loadPhotosFromFile(dataDir, "inatobsphotos.csv");
162
143
  }
163
144
 
@@ -2,25 +2,25 @@ import { ProgressMeter } from "../progressmeter.js";
2
2
  import { chunk, sleep } from "../util.js";
3
3
 
4
4
  /**
5
- @typedef {"cc-by-nc-sa"
6
- | "cc-by-nc"
7
- | "cc-by-nc-nd"
8
- | "cc-by"
9
- | "cc-by-sa"
10
- | "cc-by-nd"
11
- | "pd"
12
- | "gdfl"
13
- | "cc0"} InatLicenseCode
5
+ * @typedef {"cc0" | "cc-by" | "cc-by-nc"} AllowedLicenseCode
6
+ * @typedef {{place_id?:string,project_id?:string}} ObsPhotoLocationOptions
7
+ @typedef {{
8
+ id:number,
9
+ observation_photos: {
10
+ photo: import("./inat-tools.js").InatApiPhoto;
11
+ }[];
12
+ }} InatApiObservationPhotos
14
13
  @typedef {{
15
14
  id: string;
15
+ obsId?:string;
16
16
  ext: string;
17
- licenseCode: string;
17
+ licenseCode: AllowedLicenseCode;
18
18
  attrName: string | undefined;
19
19
  }} InatPhotoInfo
20
20
  @typedef {{
21
21
  id: number;
22
22
  attribution: string;
23
- license_code: InatLicenseCode;
23
+ license_code: string;
24
24
  medium_url?: string;
25
25
  url?: string;
26
26
  }} InatApiPhoto
@@ -30,15 +30,38 @@ import { chunk, sleep } from "../util.js";
30
30
  photo: InatApiPhoto;
31
31
  }[];
32
32
  }} InatApiTaxon
33
- @typedef {{
34
- name: string;
35
- id: number;
36
- ext: string;
37
- licenseCode: InatLicenseCode;
38
- attrName: string;
39
- }} InatCsvPhoto
33
+ @typedef {{name: string;} & InatPhotoInfo} InatCsvPhoto
40
34
  */
35
+
41
36
  const ALLOWED_LICENSE_CODES = ["cc0", "cc-by", "cc-by-nc"];
37
+ const FIELDS_OBS_PHOTO =
38
+ "(id:!t,observation_photos:(photo:(url:!t,attribution:!t,license_code:!t)))";
39
+
40
+ /**
41
+ * @param {InatApiPhoto} apiPhoto
42
+ * @returns {InatPhotoInfo|undefined}
43
+ */
44
+ export function convertToCSVPhoto(apiPhoto) {
45
+ const licenseCode = getAllowedLicenseCode(apiPhoto.license_code);
46
+ if (licenseCode === undefined) {
47
+ return;
48
+ }
49
+ const url = apiPhoto.medium_url || apiPhoto.url;
50
+ if (!url) {
51
+ return;
52
+ }
53
+ const ext = url.split(".").at(-1);
54
+ if (!ext) {
55
+ return;
56
+ }
57
+ /** @type {InatPhotoInfo} */
58
+ return {
59
+ id: apiPhoto.id.toString(),
60
+ ext: ext,
61
+ licenseCode: licenseCode,
62
+ attrName: getAttribution(apiPhoto.attribution),
63
+ };
64
+ }
42
65
 
43
66
  /**
44
67
  * @param {string[]} inatTaxonIDs
@@ -55,6 +78,122 @@ async function fetchInatTaxa(inatTaxonIDs) {
55
78
  return json.results;
56
79
  }
57
80
 
81
+ /**
82
+ * @param {import("../types.js").Taxon} taxon
83
+ * @param {{place_id?:string,project_id?:string}} locationOptions
84
+ * @return {Promise<InatApiObservationPhotos[]|Error>}
85
+ */
86
+ async function fetchObservationsForTaxon(
87
+ taxon,
88
+ locationOptions = { place_id: "14" },
89
+ ) {
90
+ const inatTaxonId = taxon.getINatID();
91
+ if (!inatTaxonId) return [];
92
+ let url = new URL(
93
+ `https://api.inaturalist.org/v2/observations/?taxon_id=${inatTaxonId}` +
94
+ "&photo_license=" +
95
+ ALLOWED_LICENSE_CODES.join(",") +
96
+ "&order=desc" +
97
+ "&order_by=votes" +
98
+ "&per_page=5",
99
+ );
100
+ url.searchParams.set("fields", FIELDS_OBS_PHOTO);
101
+ if (locationOptions.place_id) {
102
+ url.searchParams.set("place_id", locationOptions.place_id);
103
+ }
104
+ if (locationOptions.project_id) {
105
+ url.searchParams.set("project_id", locationOptions.project_id);
106
+ }
107
+ const resp = await getResponse(url);
108
+ if (resp instanceof Error) {
109
+ return resp;
110
+ }
111
+
112
+ if (!resp.ok) {
113
+ return new Error(await resp.text());
114
+ }
115
+ const json = await resp.json();
116
+ return json.results;
117
+ }
118
+
119
+ /**
120
+ * @param {string[]} obsIds
121
+ * @returns {Promise<InatApiObservationPhotos[]|Error>}
122
+ */
123
+ export async function getObsPhotosForIds(obsIds) {
124
+ let url = new URL("https://api.inaturalist.org/v2/observations/");
125
+ url.searchParams.set("fields", FIELDS_OBS_PHOTO);
126
+ url.searchParams.set("id", obsIds.join(","));
127
+ url.searchParams.set("per_page", obsIds.length.toString());
128
+
129
+ const resp = await getResponse(url);
130
+ if (resp instanceof Error) {
131
+ return resp;
132
+ }
133
+
134
+ if (!resp.ok) {
135
+ return new Error(await resp.text());
136
+ }
137
+ const json = await resp.json();
138
+ return json.results;
139
+ }
140
+
141
+ /**
142
+ * @param {import("../types.js").Taxon[]} taxaToUpdate
143
+ * @param {ObsPhotoLocationOptions|undefined} locationOptions
144
+ * @returns {Promise<Map<string,InatPhotoInfo[]>>}
145
+ */
146
+ export async function getObsPhotosForTaxa(taxaToUpdate, locationOptions) {
147
+ /** @type {Map<string,InatPhotoInfo[]>} */
148
+ const photos = new Map();
149
+
150
+ const meter = new ProgressMeter(
151
+ "retrieving observation photos",
152
+ taxaToUpdate.length,
153
+ );
154
+
155
+ for (let index = 0; index < taxaToUpdate.length; index++) {
156
+ const taxon = taxaToUpdate[index];
157
+ const observations = await fetchObservationsForTaxon(
158
+ taxon,
159
+ locationOptions,
160
+ );
161
+ if (observations instanceof Error) {
162
+ console.error(observations.message);
163
+ continue;
164
+ }
165
+
166
+ // Just get the CC-licensed ones, 5 per taxon should be fine (max is 20 on iNat). Whether or not
167
+ const rawPhotoInfo = observations
168
+ .map((obs) =>
169
+ obs.observation_photos.map((op) => {
170
+ return { obsId: obs.id, ...op.photo };
171
+ }),
172
+ )
173
+ .flat();
174
+
175
+ /** @type {InatPhotoInfo[]} */
176
+ const processedPhotoInfo = [];
177
+ for (const photo of rawPhotoInfo) {
178
+ if (processedPhotoInfo.length >= 5) {
179
+ break;
180
+ }
181
+ const obj = convertToCSVPhoto(photo);
182
+ if (!obj) {
183
+ continue;
184
+ }
185
+ processedPhotoInfo.push(obj);
186
+ }
187
+ photos.set(taxon.getName(), processedPhotoInfo);
188
+
189
+ meter.update(index + 1);
190
+ }
191
+
192
+ meter.stop();
193
+
194
+ return photos;
195
+ }
196
+
58
197
  /**
59
198
  * @param {import("../types.js").Taxon[]} taxaToUpdate
60
199
  * @returns {Promise<Map<string,InatPhotoInfo[]>>}
@@ -78,37 +217,17 @@ export async function getTaxonPhotos(taxaToUpdate) {
78
217
  for (const batch of chunk(taxaToUpdate, 30)) {
79
218
  const inatTaxa = await fetchInatTaxa(batch.map((t) => t.getINatID()));
80
219
  for (const iNatTaxon of inatTaxa) {
81
- const iNatTaxonPhotos = iNatTaxon.taxon_photos.filter((tp) =>
82
- ALLOWED_LICENSE_CODES.includes(tp.photo.license_code),
83
- );
84
-
85
220
  const taxonName = idMap.get(iNatTaxon.id.toString());
86
221
  if (!taxonName) {
87
222
  throw new Error(`iNat id ${iNatTaxon.id} not found`);
88
223
  }
89
224
  /** @type {InatPhotoInfo[]} */
90
225
  const taxonPhotos = [];
91
- for (const taxonPhoto of iNatTaxonPhotos) {
92
- const url = taxonPhoto.photo.medium_url || taxonPhoto.photo.url;
93
- if (!url) continue;
94
- const ext = url.split(".").at(-1);
95
- if (!ext) continue;
96
- /** @type {InatPhotoInfo} */
97
- const obj = {
98
- id: taxonPhoto.photo.id.toString(),
99
- ext: ext,
100
- licenseCode: taxonPhoto.photo.license_code,
101
- attrName:
102
- // Photographers retain copyright for most CC licenses,
103
- // except CC0, so attribution is a bit different
104
- taxonPhoto.photo.attribution.match(
105
- /\(c\) (.*?),/,
106
- )?.[1] ||
107
- taxonPhoto.photo.attribution.match(
108
- /uploaded by (.*)/,
109
- )?.[1],
110
- };
111
-
226
+ for (const taxonPhoto of iNatTaxon.taxon_photos) {
227
+ const obj = convertToCSVPhoto(taxonPhoto.photo);
228
+ if (!obj) {
229
+ continue;
230
+ }
112
231
  taxonPhotos.push(obj);
113
232
  }
114
233
  photos.set(taxonName, taxonPhotos);
@@ -122,3 +241,52 @@ export async function getTaxonPhotos(taxaToUpdate) {
122
241
 
123
242
  return photos;
124
243
  }
244
+
245
+ /**
246
+ * @param {string} licenseCode
247
+ * @returns {AllowedLicenseCode|undefined}
248
+ */
249
+ function getAllowedLicenseCode(licenseCode) {
250
+ switch (licenseCode) {
251
+ case "cc0":
252
+ case "cc-by":
253
+ case "cc-by-nc":
254
+ return licenseCode;
255
+ }
256
+ }
257
+
258
+ /**
259
+ * @param {string} rawAttribution
260
+ * @returns {string|undefined}
261
+ */
262
+ function getAttribution(rawAttribution) {
263
+ // Photographers retain copyright for most CC licenses,
264
+ // except CC0, so attribution is a bit different
265
+ return (
266
+ rawAttribution.match(/\(c\) (.*?),/)?.[1] ||
267
+ rawAttribution.match(/uploaded by (.*)/)?.[1]
268
+ );
269
+ }
270
+
271
+ let lastQueryTime = Date.now();
272
+ /**
273
+ * @param {URL} url
274
+ * @returns {Promise<Response|Error>}
275
+ */
276
+ async function getResponse(url) {
277
+ // If less than one second since last query, delay.
278
+ const delayTime = 1050 - (Date.now() - lastQueryTime);
279
+ if (delayTime > 0) {
280
+ await sleep(delayTime);
281
+ }
282
+
283
+ try {
284
+ lastQueryTime = Date.now();
285
+ return await fetch(url);
286
+ } catch (error) {
287
+ if (error instanceof Error) {
288
+ return error;
289
+ }
290
+ throw error;
291
+ }
292
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ca-plant-list/ca-plant-list",
3
- "version": "0.4.31",
3
+ "version": "0.4.33",
4
4
  "description": "Tools to create files for a website listing plants in an area of California.",
5
5
  "license": "MIT",
6
6
  "repository": {