Code, design and documents 6 files
docs/DATA-MAINTENANCE.md +5 −3
@@ -255,7 +255,7 @@ context:
planting:
seeds: grey # may an adult have and plant them: legal | grey | licensed | illegal
- seeds_trade: open # may they be sold or handed on: open | regulated | gift | unclear | banned
+ seeds_trade: open # open | regulated-sale-plus-gifts | regulated | gift | unclear | banned
clones: illegal # same four values as seeds
- clones_trade: banned # same five values as seeds_trade
+ clones_trade: banned # same values as seeds_trade
text: >-
The Misuse of Drugs Act's definition of cannabis leaves out the seed, so buying and holding
@@ -280,4 +280,5 @@ to sell them a plant.
|---|---|
| `open` | Anyone may sell them, in shops or online |
+| `regulated-sale-plus-gifts` | Licensed sellers may sell them, and adults may also give a limited amount away |
| `regulated` | Only licensed sellers, clubs or the state may sell or hand them out, often with limits |
| `gift` | May be given away between adults, but not sold |
@@ -292,5 +293,6 @@ How to decide:
cutting is a plant unless the law says otherwise.
- For the trade status, look for who may sell: nobody (`banned`), a licence holder or club
- (`regulated`), anyone (`open`). Where seeds are simply outside the definition of cannabis and no
+ (`regulated`), anyone (`open`). Where licensed sellers may sell and adults may also give a
+ limited amount away, use `regulated-sale-plus-gifts`. Where seeds are simply outside the definition of cannabis and no
other rule restricts them, the trade is `open`. Use `unclear` when the law allows having them but
is silent on selling, and say so in the text.
docs/research/profile-legal-ca-nv-wa-2026-10-23.md +51 −0
@@ -0,0 +1,51 @@
+# Canada seeds and clones, Nevada gifts, Washington medical growing — 23 October 2026
+
+Issues #41, #45 and #48. Scores were left as they were.
+
+## Canada
+
+Read on 23 October 2026:
+
+- Cannabis Act section 9, current to 30 September 2026. An adult may not distribute more than 30 g dried equivalent, a budding or flowering plant, or more than four plants that are not budding or flowering. `Distribute` includes giving.
+- Section 10. Selling cannabis is prohibited unless authorized under the Act.
+- Section 12. Four plants per dwelling-house, including where more than one adult lives there. Cultivating from seed or plant material the person knows is illicit is prohibited.
+- Section 8(1)(e), read in the interpretation page's text of section 8. Possessing more than four non-budding, non-flowering plants is prohibited.
+- Schedule 3 item 7, in the consolidated full text. One cannabis plant seed equals 1 g of dried cannabis. Subsection 2(4) applies that table.
+- Health Canada, Legislative Review of the Cannabis Act, Chapter 8. Adults may share up to 30 cannabis seeds and four non-flowering plants. Quebec and Manitoba prohibit home cultivation. Newfoundland and Labrador and the Northwest Territories prohibit outdoor home cultivation.
+- Health Canada, Growing cannabis at home safely. Buy seeds or immature flowering plants from an authorised retailer. Growing from a source the person knows is illegal is an offence. Adults may share up to 30 g of personally grown cannabis and may not sell without a licence.
+
+The trade status `regulated` means only a licensed seller may sell or hand the material out. Canada allows both licensed sales and adult gifts, so seeds and clones use the new status `regulated-sale-plus-gifts`. Commercial sale is not `open`. The map uses the same colour as regulated sales because the freedom scale has no spare step between those two.
+
+Possession stays 6, cultivation stays 4, sharing stays 5. Planting is unscored.
+
+## Nevada
+
+Read NRS 678D, the 2025 revision updated 15 April 2026, and Senate Bill 277, Chapter 423 of the 2023 Statutes, approved 14 June 2023.
+
+NRS 678D.200(3)(f) allows a person 21 or older to deliver 2.5 ounces or less of usable cannabis, or one-fourth of an ounce or less of concentrated cannabis, without remuneration to a person 21 or older, if the delivery is not advertised or promoted to the public. Subsection (3)(e) allows six plants in a locked enclosure out of public view, at a residence with no more than twelve plants. Subsection (3)(d) is the matching possession limit.
+
+NRS 678D.310 forbids cultivation within 25 miles of a licensed adult-use retail store, cultivation visible from a public place, and cultivation without the property holder's consent, except as chapter 678C provides. The first violation is a misdemeanour fine of not more than $600. A fourth or subsequent violation is a category E felony. The chapter does not say that twelve plants at a residence is a felony.
+
+Senate Bill 277, section 14, replaced one ounce and one-eighth of an ounce with 2.5 ounces and one-fourth of an ounce. Section 19 makes sections 1 to 15.5 effective on 1 January 2024 for purposes other than preparatory regulations. The history entry is unscored because it is one state.
+
+The Division of Public and Behavioral Health FAQ lists four medical home-cultivation exceptions: no dispensary within 25 miles, that distance at the first application with no lapse, inability to travel because of illness or lack of transportation, and a local dispensary that cannot supply the needed strain. The FAQ does not state a plant count.
+
+The profile no longer says that possessing more than 2.5 ounces is a misdemeanour with a $600 fine. The $600 figure in this chapter is the first cultivation violation and public consumption. The penalty for exceeding the possession exemption was not read. The sentence that licensed consumption lounges operate in Las Vegas was already in the summary and was not re-checked.
+
+Sharing stays 5. Cultivation stays 2. The six-plant permission applies only outside the 25-mile limit, or under a medical exception, so it was not rescored as generally legal home growing.
+
+The definition of usable cannabis, NRS 678D.040, is marked repealed in the chapter heading. The operative section still uses the term. No replacement definition was read.
+
+## Washington
+
+Read RCW 69.50.360, 69.50.4013, 69.50.4014, 69.50.401, 69.50.204, 69.51A.210 and 69.51A.040, and the disposition page for RCW 69.50.425.
+
+69.51A.210(3) lets a qualifying patient or designated provider with an authorization who is not in the database grow four plants in the domicile and possess six ounces there. Subsection (1) is six plants and eight ounces once the person is in the database. Subsection (2) is up to fifteen plants and sixteen ounces when the health-care professional says the need is greater. 69.51A.040 protects possession and manufacture within those amounts when the person shows the card or authorization and posts a copy next to the plants. A person who is both a patient and a designated provider may hold twice the amounts, and no more than fifteen plants in one housing unit.
+
+69.50.4013(4) is the adult gift: half an ounce of useable cannabis, or the listed product amounts, in one 24-hour period, without payment, out of public view in a nonpublic place or in the original retailer packaging. 69.50.360(3) is the possession allowance that 4013(3) incorporates, including one ounce of useable cannabis. 69.50.4014 makes knowing possession of 40 grams or less a misdemeanour and sets no mandatory jail term. 69.50.4013(2) makes knowing possession that is not within 4014 a gross misdemeanour. Cannabis is Schedule I under 69.50.204. Unauthorized manufacture or delivery is a class C felony under 69.50.401.
+
+The disposition page says RCW 69.50.425, titled "Misdemeanor violations—Minimum penalties", was repealed by 2015 2nd sp.s. c 4 § 1602, effective 1 July 2015. The repealed text itself was not opened, and the Office of Financial Management fiscal note was not opened. The profile no longer states a 24-hour mandatory minimum.
+
+The $50 public-consumption penalty was already in the profile and was not re-read.
+
+Possession stays 5, cultivation stays 1, sharing stays 4. The gift is lawful up to a cap with place and packaging conditions, which is why sharing was left between a grey area and an unqualified capped gift.
scripts/history-scope.test.cjs +42 −0
@@ -464,2 +464,44 @@ test("Colorado gifts and household plants, and D.C. indoor growing, follow the t
assert.equal(dc.scores.sharing, 5);
});
+
+test("Canada's seed gifts, Nevada's 2024 limits, and Washington's medical grow follow the texts that were read", () => {
+ const ca = y.load(fs.readFileSync("countries/ca/index.yaml", "utf8"));
+ const nv = y.load(fs.readFileSync("countries/us/nv.yaml", "utf8"));
+ const wa = y.load(fs.readFileSync("countries/us/wa.yaml", "utf8"));
+ const nevada = byId["nevada-adult-limits-raised-2024"];
+ assert.equal(ca.context.planting.seeds_trade, "regulated-sale-plus-gifts");
+ assert.equal(ca.context.planting.clones_trade, "regulated-sale-plus-gifts");
+ assert.match(ca.context.planting.text, /30 cannabis seeds/);
+ assert.match(ca.context.planting.text, /four plants that are not budding or flowering/);
+ assert.match(ca.context.planting.text, /Selling cannabis without authorisation is prohibited/);
+ assert.match(ca.segments.cultivation.text, /does not know is illicit/);
+ assert.match(ca.segments.cultivation.text, /Manitoba/);
+ assert.equal(ca.scores.possession, 6);
+ assert.equal(ca.scores.cultivation, 4);
+ assert.equal(ca.scores.sharing, 5);
+ assert.match(nv.segments.sharing, /2\.5 ounces/);
+ assert.match(nv.segments.sharing, /one-fourth of an ounce/);
+ assert.match(nv.segments.sharing, /not advertised or promoted/);
+ assert.doesNotMatch(nv.segments.sharing, /1 oz of flower/);
+ assert.match(nv.segments.cultivation, /no more than twelve/);
+ assert.match(nv.segments.cultivation, /\$600/);
+ assert.doesNotMatch(nv.segments.cultivation, /Twelve plants or more is a felony/);
+ assert.equal(nv.scores.sharing, 5);
+ assert.equal(nv.scores.cultivation, 2);
+ assert.equal(nevada.date, "2024-01-01");
+ assert.equal(nevada.before, undefined);
+ assert.equal(nevada.subunit, "nv");
+ assert.match(nevada.unscored, /national score does not move/);
+ assert.match(wa.segments.cultivation, /four plants/);
+ assert.match(wa.segments.cultivation, /not in the medical cannabis database/);
+ assert.match(wa.segments.cultivation, /Schedule I/);
+ assert.doesNotMatch(wa.segments.cultivation, /registered medical patient/);
+ assert.match(wa.segments.sharing, /one-half ounce/);
+ assert.match(wa.segments.sharing, /24-hour period/);
+ assert.match(wa.segments.sharing, /original retailer packaging/);
+ assert.doesNotMatch(wa.segments.possession, /24-hour mandatory/);
+ assert.match(wa.segments.possession, /gross misdemeanour/);
+ assert.equal(wa.scores.possession, 5);
+ assert.equal(wa.scores.cultivation, 1);
+ assert.equal(wa.scores.sharing, 4);
+});
src/components/HomePage.astro +3 −2
@@ -122,5 +122,6 @@ const PRICE_SCALE = {
const PLANTING_FIELDS = { seeds: "Seeds", seeds_trade: "Seed sales", clones: "Clones", clones_trade: "Clone sales" };
// Each status gets its own step of the tier colours, so that no two legend entries look alike.
-const PLANTING_COLOR = { legal: 5, licensed: 4, grey: 3, illegal: 0, open: 5, regulated: 4, gift: 3, unclear: 2, banned: 0 };
+// `regulated-sale-plus-gifts` shares step 4 with `regulated`: the scale has no step between open and regulated.
+const PLANTING_COLOR = { legal: 5, licensed: 4, grey: 3, illegal: 0, open: 5, "regulated-sale-plus-gifts": 4, regulated: 4, gift: 3, unclear: 2, banned: 0 };
const plantingScale = (statuses) => Object.fromEntries(Object.entries(statuses).map(([k, v]) => [k, { label: v.label, help: v.help, color: `var(--t${PLANTING_COLOR[k]})` }]));
const PLANTING_SCALES = { status: plantingScale(PLANTING_STATUS), trade: plantingScale(PLANTING_TRADE) };
@@ -157,5 +158,5 @@ const streetFlower = (c) => latestPricesFor(c.id).street;
// Extra columns sort on a number kept on the row: higher means freer (or bigger), -1 means no data.
const order = (keys) => Object.fromEntries(keys.map((k, i) => [k, keys.length - i]));
-const STATUS_RANK = { ...order(Object.keys(PLANTING_STATUS)), ...order(["open", "regulated", "gift", "unclear", "banned"]) };
+const STATUS_RANK = { ...order(Object.keys(PLANTING_STATUS)), ...order(["open", "regulated-sale-plus-gifts", "regulated", "gift", "unclear", "banned"]) };
const statusCol = (key, label, vocab, helpIndex) => ({
key, label, group: "Context",
src/lib/map-views.js +1 −1
@@ -37,5 +37,5 @@ export const MAP_VIEWS = [
lede: "Whether an adult may have and sow cannabis seeds in each country. Hatched countries have not been researched yet." },
{ slug: "seed-sales", metric: "plant:seeds_trade", column: "seeds_trade", title: "Where cannabis seeds can be sold",
- lede: "Whether cannabis seeds may be sold or handed on in each country: freely, by regulated sellers only, as gifts, or not at all." },
+ lede: "Whether cannabis seeds may be sold or handed on in each country: freely, by licensed sellers with adult gifts also allowed, by regulated sellers only, as gifts, or not at all." },
{ slug: "clones", metric: "plant:clones", column: "clones", title: "Where cannabis clones are legal",
lede: "Whether an adult may have and grow cannabis cuttings in each country. Hatched countries have not been researched yet." },
src/lib/segment-ids.js +1 −0
@@ -14,4 +14,5 @@ export const PLANTING_STATUS = {
export const PLANTING_TRADE = {
open: { label: "Sold freely", tone: "legal", help: ["Anyone may sell them, in shops or online", "Anyone may sell them, in shops or online"] },
+ "regulated-sale-plus-gifts": { label: "Licensed sales and gifts", tone: "partial", help: ["Licensed sellers may sell them, and adults may also give a limited amount away", "Licensed sellers may sell them, and adults may also give a limited amount away"] },
regulated: { label: "Regulated sellers only", tone: "partial", help: ["Only licensed sellers, clubs or the state may sell or hand them out, often with limits", "Only licensed sellers, clubs or the state may sell or hand them out, often with limits"] },
gift: { label: "Gifts only", tone: "decrim", help: ["May be given away between adults, but not sold", "May be given away between adults, but not sold"] },