{"version":3,"file":"Marketing-BA5BI45p.js","sources":["../../../node_modules/@turf/circle/dist/esm/index.js","../../../app/javascript/components/public-suitability-tool/components/basic.jsx","../../../app/javascript/components/public-suitability-tool/constants.jsx","../../../node_modules/p-cancelable/index.js","../../../app/javascript/components/public-suitability-tool/helpers.js","../../../app/javascript/components/public-suitability-tool/components/LandBoundariesLayer.jsx","../../../app/javascript/components/public-suitability-tool/components/CTAPanel.jsx","../../../app/javascript/utils/loadTilesetsMetadata.js","../../../app/javascript/utils/webgl/suitability-calculations/suitabilityAcrossLayers.js","../../../app/javascript/components/public-suitability-tool/hooks.js","../../../app/javascript/components/public-suitability-tool/components/GreenButton.jsx","../../../app/javascript/components/public-suitability-tool/components/CropInfo.jsx","../../../app/javascript/components/public-suitability-tool/components/InfoPanel.jsx","../../../app/javascript/components/public-suitability-tool/components/PostSubmit.jsx","../../../app/javascript/utils/submitMarketingInbound.js","../../../app/javascript/hooks/useAsSequentialAsync.js","../../../app/javascript/components/public-suitability-tool/PublicSuitabilityTool.jsx","../../../app/javascript/routes/MarketingRoutes.tsx","../../../app/javascript/entrypoints/Marketing.jsx"],"sourcesContent":["// index.ts\nimport { destination } from \"@turf/destination\";\nimport { polygon } from \"@turf/helpers\";\nfunction circle(center, radius, options = {}) {\n const steps = options.steps || 64;\n const properties = options.properties ? options.properties : !Array.isArray(center) && center.type === \"Feature\" && center.properties ? center.properties : {};\n const coordinates = [];\n for (let i = 0; i < steps; i++) {\n coordinates.push(\n destination(center, radius, i * -360 / steps, options).geometry.coordinates\n );\n }\n coordinates.push(coordinates[0]);\n return polygon([coordinates], properties);\n}\nvar turf_circle_default = circle;\nexport {\n circle,\n turf_circle_default as default\n};\n//# sourceMappingURL=index.js.map","import styled from 'styled-components';\nimport { Button } from 'reactstrap';\n\nimport { BREAKPOINTS, useBreakpointSize } from '../../../utils/responsive';\n\nconst DROP_SHADOW = 'box-shadow: 2px 2px 4px 2px rgb(0 0 0 / 20%);';\n\nexport const MainContainer = styled.div`\n position: relative;\n\n height: 100vh; // fallback\n height: 100dvh;\n\n width: 100vw;\n max-width: 1800px;\n\n margin: 0 auto;\n overflow: hidden;\n\n display: flex;\n\n flex-direction: column;\n @media (min-width: ${BREAKPOINTS.lg}) {\n flex-direction: row;\n max-height: 1200px;\n }\n\n background-color: white;\n\n /* class for buttons on map to make them match the cards better */\n .map-button {\n ${DROP_SHADOW}\n background-color: #fff !important;\n font-size: 15.6px;\n\n width: fit-content;\n }\n`;\n\nexport const FullOverlay = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(64, 64, 64, 0.75);\n z-index: 1001;\n\n display: flex;\n justify-content: center;\n align-items: center;\n`;\n\n// styles to match reactstrap buttons, plus drop shadow + more padding\nconst CardBase = styled.div`\n color: #212529;\n background-color: #fff;\n border-color: var(--border-color);\n border-radius: 3px;\n\n padding: 16px;\n\n ${DROP_SHADOW}\n`;\n\nexport const LoadingCard = styled(CardBase)`\n display: flex;\n flex-direction: column;\n max-width: calc(100vw - 32px);\n text-align: center;\n\n width: 300px;\n padding: 16px;\n font-size: 15.6px;\n\n @media (min-width: ${BREAKPOINTS.md}) {\n width: 420px;\n padding: 24px;\n font-size: 20px;\n }\n`;\n\nexport const PromptCard = styled(CardBase)`\n max-width: calc(100vw - 32px);\n text-align: center;\n\n width: 380px;\n padding: 16px;\n font-size: 15.6px;\n\n @media (min-width: ${BREAKPOINTS.md}) {\n width: 480px;\n padding: 24px;\n font-size: 20px;\n }\n`;\n\nexport const InfoCard = styled(CardBase)`\n font-size: 15.6px;\n`;\n\nexport const InfoText = styled.div`\n color: white;\n text-shadow: 0 0 16px rgb(0 0 0 / 50%);\n text-align: center;\n\n font-size: 18px;\n padding: 0 16px 12px;\n @media (min-width: ${BREAKPOINTS.md}) {\n font-size: 20px;\n padding: 0 16px 16px;\n }\n @media (min-width: ${BREAKPOINTS.lg}) {\n font-size: 26px;\n }\n`;\n\n// Add xs size to reactstrap Button\nconst ButtonWithXs = styled(Button)`\n &.btn-xs {\n padding: 2px 6px;\n font-size: 12px;\n\n @media (min-width: ${BREAKPOINTS.xs}) {\n font-size: 13px;\n }\n }\n`;\n\n/**\n * Extension of reactstrap Button with responsive sizing.\n *\n * Pass `sizes`, an array of strings, e.g. ['xs', 'sm', 'md', 'lg'], to specify\n * which sizes can be used.\n */\nexport const ResponsiveButton = ({ sizes = ['sm', 'md', 'lg'], ...props }) => {\n const size = useBreakpointSize(sizes);\n return ;\n};\n\nexport const DemoMapBackground = () => (\n \n);\n\nexport const LinkNewTab = ({ href, children }) => (\n \n {children}\n \n);\n","import { LinkNewTab } from './components/basic';\nimport {\n CHINESE_CHESTNUT_TILESET_NAME,\n BLACK_LOCUST_TILESET_NAME,\n HYBRID_POPLAR_TILESET_NAME,\n BLACKCURRANT_TILESET_NAME,\n AMERICAN_ELDERBERRY_TILESET_NAME,\n AMERICAN_HAZELNUT_TILESET_NAME,\n} from '../../constants/tilesets';\n\nexport const LAND_BOUNDARIES_PREFIX = 'land-boundaries';\nexport const MAIN_SOURCE_ID = `${LAND_BOUNDARIES_PREFIX}-source`;\n\nexport const CLU_PADDING_FACTOR = 1.2;\nexport const CLU_TIMEOUT = 15 * 1000;\n\nexport const ZOOM_FOR_ADDRESS = 15.5;\nexport const ZOOM_FOR_FALLBACK = 15;\n\nexport const FALLBACK_FEATURE_ID = 'fallback-feature';\nexport const FALLBACK_FEATURE_RADIUS = {\n value: 1000,\n units: 'meters',\n}; // 1km radius -> ~750 acres\n\n// (coords of demo bg image)\nexport const INIT_MAP_POSITION = {\n lat: 42.50625,\n lng: -76.5875,\n zoom: 15.5,\n};\n\n// Note: id is the tileset id, name is the crop name\nexport const TILESET_SPEC = [\n { name: CHINESE_CHESTNUT_TILESET_NAME, displayName: 'Chinese Chestnut' },\n { name: BLACK_LOCUST_TILESET_NAME, displayName: 'Black Locust' },\n { name: HYBRID_POPLAR_TILESET_NAME, displayName: 'Hybrid Poplar' },\n { name: BLACKCURRANT_TILESET_NAME, displayName: 'Blackcurrant' },\n {\n name: AMERICAN_ELDERBERRY_TILESET_NAME,\n displayName: 'American Elderberry',\n },\n { name: AMERICAN_HAZELNUT_TILESET_NAME, displayName: 'American Hazelnut' },\n];\n\nexport const INIT_SELECTED_FEATURE_IDS_STATE = {}; // (stable object reference)\n\nexport const STEPS = {\n INPUT_ADDRESS: 'INPUT_ADDRESS',\n LOADING_BOUNDARIES: 'LOADING_BOUNDARIES',\n BOUNDARY_LOAD_FAILURE: 'BOUNDARY_LOAD_FAILURE',\n DRAW_MODE_PROMPT: 'DRAW_MODE_PROMPT',\n SELECT_REGIONS: 'SELECT_REGIONS',\n POST_SUBMIT: 'POST_SUBMIT',\n};\n\nexport const PUBLIC_CLU_BASE_PATH = '/api/public/clu';\n\nexport const LOADING_MESSAGES = [\n null,\n 'Loading land parcel boundaries...',\n 'Loading crop suitability...',\n 'Loading is taking longer than usual...',\n];\n\nexport const LOADING_MESSAGE_DURATION = 5 * 1000;\n\nexport const SIDE_PANEL_WIDTHS = {\n md: '275px',\n lg: '360px',\n};\n\nexport const SUITABILITY_INPUTS = [\n 'pH',\n 'Soil Texture',\n 'Depth to RL',\n 'Depth to WT',\n 'Hydric Rate',\n 'Drainage',\n 'Flooding',\n 'Steepness',\n 'Heaving',\n];\n\nexport const DRAWN_FEATURE_ID_PREFIX = 'drawn-feature-';\n\nexport const CROP_INFOS = {\n [CHINESE_CHESTNUT_TILESET_NAME]: {\n description: (\n <>\n \n Chinese chestnuts\n {' '}\n are a perennial crop that helps farms diversify their crop production\n and improve overall profit per acre. These trees also help farms adapt\n to, and mitigate effects from extreme weather like drought and flooding.\n Today, U.S. production lags behind domestic demand, making for an\n enticing opportunity.\n \n ),\n },\n [BLACK_LOCUST_TILESET_NAME]: {\n description: (\n <>\n \n Black locust\n {' '}\n is a fast-growing, high-value hardwood. The lumber is 30% stronger than\n white oak, and lasts for 30+ years in contact with the soil. Black\n locust lumber prices surpasses black walnut prices, and the tree reaches\n sawlog size in one-third of the time. Black locust is at the forefront\n of market-driven climate solutions in cold, humid climates.\n
\n
\n Reach out to learn about our exclusive license to the Turbo Obelisk\n variety group, a line of elite Robinia genetics with a straight growth\n form and exceptional growth rate.\n \n ),\n },\n [HYBRID_POPLAR_TILESET_NAME]: {\n description: (\n <>\n \n Hybrid Poplar\n {' '}\n is an excellent fast-growing tree, tolerant of wet feet and saturated\n soils. The tree yields functional lumber after 20 year or fewer, but\n must be harvested before it senesces. Planting hybrid poplar is\n analogous to keeping money in treasury bonds or a savings account for 20\n years, rather than a portfolio of stocks. Trees such as black walnut and\n larch also yield modest returns over 40+ years.\n \n ),\n },\n [BLACKCURRANT_TILESET_NAME]: {\n description: (\n <>\n \n Blackcurrants\n {' '}\n are a popular commodity crop outside of the US, and coming into\n production domestically. With up to 5 lbs of yield per stem,\n blackcurrants can be sold wholesale as berries, fresh or frozen, or as\n juice. They are proving to be a productive and marketable crop with\n opportunities for cold-climate growers.\n \n ),\n },\n [AMERICAN_ELDERBERRY_TILESET_NAME]: {\n description: (\n <>\n Elderberries are a multi-use plant with a growing market in the US\n focused on the food-medicine qualities of the berries. Beyond the\n value-add market, they also have on-farm benefits in silvopasture\n systems. Learn more about Propagate's hen-silvopasture project with\n Handsome Brook Farms{' '}\n \n here\n \n .\n \n ),\n },\n [AMERICAN_HAZELNUT_TILESET_NAME]: {\n description: (\n <>\n Hazelnuts are a perennial crop that can yield decades of low-input nut\n production. While eastern fulbright blight has prevented\n commercialization of hazelnuts in the Eastern US, Propagate has worked\n with cultivars resistant to the fungal pathogen to set up working\n buffers on sub-prime and underutilized acreage in the Northeast.{' '}\n \n Learn more\n \n .\n \n ),\n },\n};\n","export class CancelError extends Error {\n\tconstructor(reason) {\n\t\tsuper(reason || 'Promise was canceled');\n\t\tthis.name = 'CancelError';\n\t}\n\n\tget isCanceled() {\n\t\treturn true;\n\t}\n}\n\nconst promiseState = Object.freeze({\n\tpending: Symbol('pending'),\n\tcanceled: Symbol('canceled'),\n\tresolved: Symbol('resolved'),\n\trejected: Symbol('rejected'),\n});\n\nexport default class PCancelable {\n\tstatic fn(userFunction) {\n\t\treturn (...arguments_) => new PCancelable((resolve, reject, onCancel) => {\n\t\t\targuments_.push(onCancel);\n\t\t\tuserFunction(...arguments_).then(resolve, reject);\n\t\t});\n\t}\n\n\t#cancelHandlers = [];\n\t#rejectOnCancel = true;\n\t#state = promiseState.pending;\n\t#promise;\n\t#reject;\n\n\tconstructor(executor) {\n\t\tthis.#promise = new Promise((resolve, reject) => {\n\t\t\tthis.#reject = reject;\n\n\t\t\tconst onResolve = value => {\n\t\t\t\tif (this.#state !== promiseState.canceled || !onCancel.shouldReject) {\n\t\t\t\t\tresolve(value);\n\t\t\t\t\tthis.#setState(promiseState.resolved);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst onReject = error => {\n\t\t\t\tif (this.#state !== promiseState.canceled || !onCancel.shouldReject) {\n\t\t\t\t\treject(error);\n\t\t\t\t\tthis.#setState(promiseState.rejected);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst onCancel = handler => {\n\t\t\t\tif (this.#state !== promiseState.pending) {\n\t\t\t\t\tthrow new Error(`The \\`onCancel\\` handler was attached after the promise ${this.#state.description}.`);\n\t\t\t\t}\n\n\t\t\t\tthis.#cancelHandlers.push(handler);\n\t\t\t};\n\n\t\t\tObject.defineProperties(onCancel, {\n\t\t\t\tshouldReject: {\n\t\t\t\t\tget: () => this.#rejectOnCancel,\n\t\t\t\t\tset: boolean => {\n\t\t\t\t\t\tthis.#rejectOnCancel = boolean;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\n\t\t\texecutor(onResolve, onReject, onCancel);\n\t\t});\n\t}\n\n\t// eslint-disable-next-line unicorn/no-thenable\n\tthen(onFulfilled, onRejected) {\n\t\treturn this.#promise.then(onFulfilled, onRejected);\n\t}\n\n\tcatch(onRejected) {\n\t\treturn this.#promise.catch(onRejected);\n\t}\n\n\tfinally(onFinally) {\n\t\treturn this.#promise.finally(onFinally);\n\t}\n\n\tcancel(reason) {\n\t\tif (this.#state !== promiseState.pending) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#setState(promiseState.canceled);\n\n\t\tif (this.#cancelHandlers.length > 0) {\n\t\t\ttry {\n\t\t\t\tfor (const handler of this.#cancelHandlers) {\n\t\t\t\t\thandler();\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthis.#reject(error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (this.#rejectOnCancel) {\n\t\t\tthis.#reject(new CancelError(reason));\n\t\t}\n\t}\n\n\tget isCanceled() {\n\t\treturn this.#state === promiseState.canceled;\n\t}\n\n\t#setState(state) {\n\t\tif (this.#state === promiseState.pending) {\n\t\t\tthis.#state = state;\n\t\t}\n\t}\n}\n\nObject.setPrototypeOf(PCancelable.prototype, Promise.prototype);\n","import _ from 'lodash';\nimport * as turf from '@turf/turf';\nimport PCancelable from 'p-cancelable';\n\nimport {\n CLU_PADDING_FACTOR,\n CLU_TIMEOUT,\n FALLBACK_FEATURE_ID,\n FALLBACK_FEATURE_RADIUS,\n MAIN_SOURCE_ID,\n PUBLIC_CLU_BASE_PATH,\n ZOOM_FOR_ADDRESS,\n ZOOM_FOR_FALLBACK,\n} from './constants';\nimport loadCluBoundaries from '../../utils/loadCluBoundaries';\nimport { waitForSuccess } from '../../utils/utils';\nimport { setSourceData } from '../../utils/map';\nimport { layerIdForTileset } from '../../utils/tilesets';\n\n/**\n * Sorts tilesets by suitability (desc) and then by name (asc) but putting Chestnuts first for name.\n */\nexport const sortTilesetSuitability = (tilesets) =>\n _.sortBy(tilesets, [(t) => -(t.suitableAcres ?? 0), 'name']);\n\nexport const getSelectedFeatures = (map, selectedFeatureIds) => {\n const features = map.querySourceFeatures(MAIN_SOURCE_ID);\n const selectedFeatures = features.filter((feature) =>\n selectedFeatureIds.includes(feature.properties.id),\n );\n return _.uniqBy(selectedFeatures, 'properties.id');\n};\n\n/**\n * Load CLU data to the map, or time out.\n */\nexport const loadCluToMapWithTimeout = async (\n mapRef,\n { merge = false } = {},\n) => {\n const map = mapRef.current;\n if (!map) throw new Error('Map not loaded');\n\n const source = mapRef.current.getSource(MAIN_SOURCE_ID);\n if (!source) throw new Error('CLU source not found in mapbox');\n\n // NOTE: this only loads features that are nearby the current view, but that's fine for this use case:\n const existingFeatures = mapRef.current.querySourceFeatures(MAIN_SOURCE_ID);\n\n let completed = false;\n\n const cancelablePromise = PCancelable.fn(async (onCancel) => {\n let cancelled = false;\n onCancel(() => {\n cancelled = true;\n });\n\n try {\n const currentZoom = map.getZoom();\n if (currentZoom !== ZOOM_FOR_ADDRESS) {\n map.setZoom(ZOOM_FOR_ADDRESS);\n\n // Wait for the zoom to complete (this shouldn't be necessary, but it seems to be)\n await waitForSuccess(\n () => Math.abs(map.getZoom() - ZOOM_FOR_ADDRESS) < 0.01, // allow for floating point error\n );\n }\n\n // Fetch the CLU features\n const { features: newFeatures } = await loadCluBoundaries(\n mapRef,\n PUBLIC_CLU_BASE_PATH,\n CLU_PADDING_FACTOR,\n );\n\n // If we've been cancelled by the timeout, return early\n if (cancelled) return;\n\n // Add the features to the map\n let newData = turf.featureCollection(newFeatures);\n if (merge) {\n const newFeatureIds = new Set(newFeatures.map((f) => f.properties.id));\n newData = turf.featureCollection([\n ...newFeatures,\n ...existingFeatures.filter(\n (f) =>\n !newFeatureIds.has(f.properties.id) && // no duplicates\n f.properties.id !== FALLBACK_FEATURE_ID, // don't keep the fallback circle\n ),\n ]);\n }\n\n source.setData(newData);\n } finally {\n completed = true;\n }\n })();\n\n setTimeout(() => {\n if (!completed) {\n cancelablePromise.cancel();\n throw new Error('CLU data loading timeout');\n }\n }, CLU_TIMEOUT);\n\n return cancelablePromise;\n};\n\n/**\n * If loading CLU fails, add a circle to the map as a fallback\n */\nexport const addFallbackBoundary = async (\n mapRef,\n toggleFeatureId,\n resetSelectedFeatures,\n) => {\n const map = mapRef.current;\n if (!map) throw new Error('Map not loaded');\n\n const id = FALLBACK_FEATURE_ID;\n\n map.setZoom(ZOOM_FOR_FALLBACK);\n\n const { lng, lat } = map.getCenter();\n const { value, units } = FALLBACK_FEATURE_RADIUS;\n const feature = turf.circle([lng, lat], value, {\n units,\n properties: { id },\n });\n\n const data = turf.featureCollection([feature]);\n await setSourceData(map, MAIN_SOURCE_ID, data);\n\n // Select the circle\n resetSelectedFeatures();\n toggleFeatureId(id);\n};\n\nexport const layerForTileset = (map, tilesetId) =>\n map.getLayer(layerIdForTileset(tilesetId))?.implementation;\n\nexport const getNonFallbackFeatures = (map) =>\n map\n .querySourceFeatures(MAIN_SOURCE_ID)\n .filter((f) => f.properties.id !== FALLBACK_FEATURE_ID);\n","import { useEffect, useState } from 'react';\nimport { useLatest } from 'react-use';\nimport { featureCollection } from '@turf/turf';\n\nimport { emptyFeature, emptyGeojson } from '../../../utils/geojson';\nimport {\n FALLBACK_FEATURE_ID,\n MAIN_SOURCE_ID,\n LAND_BOUNDARIES_PREFIX as PREFIX,\n} from '../constants';\nimport { getSelectedFeatures } from '../helpers';\n\nconst SELECTED_FEATURES_SOURCE_ID = `${PREFIX}-selected-features-source`;\nconst HOVERED_FEATURE_SOURCE_ID = `${PREFIX}-hovered-feature-source`;\n\nconst MAIN_LAYER_ID = `${PREFIX}-layer`;\nconst SELECTED_FEATURES_LAYER_ID = `${PREFIX}-selected-features-layer`;\nconst HOVERED_FEATURE_LAYER_ID = `${PREFIX}-hovered-feature-layer`;\nconst INTERACTION_LAYER_ID = `${PREFIX}-interaction-layer`;\n\nconst MAIN_COLOR = '#820000';\nconst HOVERED_COLOR = '#cccccc';\nconst SELECTED_COLOR = '#61a0ff';\n\n// These are necessary to prevent some nasty mapbox bugs\n// See https://github.com/mapbox/mapbox-gl-js/issues/7023\nconst SOURCE_SETTINGS = {\n // Setting tolerance to 0 reduces bugs related to coordinate conversions\n tolerance: 0,\n // Setting buffer to its max value and maxzoom to its min value reduces bugs related to tile cutoff when zooming\n buffer: 512,\n maxzoom: 12,\n // Setting promoteId to 'id' helps mapbox de-dup features with the same id\n promoteId: 'id',\n};\n\nconst LandBoundariesLayer = ({\n mapRef,\n selectedFeatureIds,\n toggleFeatureId,\n isDrawMode,\n}) => {\n // State for hovered feature:\n const [hoveredFeatureId, setHoveredFeatureId] = useState(null);\n\n // Ref for access without stale state within the useEffect\n const selectedFeatureIdsRef = useLatest(selectedFeatureIds);\n const isDrawModeRef = useLatest(isDrawMode);\n\n // Add the layers to the map\n useEffect(() => {\n const map = mapRef.current;\n if (!map) return null;\n\n // main source\n map.addSource(MAIN_SOURCE_ID, emptyGeojson(SOURCE_SETTINGS));\n\n // source for just the selected features\n map.addSource(SELECTED_FEATURES_SOURCE_ID, emptyGeojson(SOURCE_SETTINGS));\n\n // source for just the hovered feature\n map.addSource(HOVERED_FEATURE_SOURCE_ID, emptyGeojson(SOURCE_SETTINGS));\n\n // main layer\n map.addLayer({\n id: MAIN_LAYER_ID,\n source: MAIN_SOURCE_ID,\n type: 'line',\n layout: {\n 'line-join': 'round',\n 'line-cap': 'round',\n },\n paint: {\n 'line-color': MAIN_COLOR,\n 'line-width': 2,\n },\n });\n\n // main layer\n map.addLayer({\n id: SELECTED_FEATURES_LAYER_ID,\n source: SELECTED_FEATURES_SOURCE_ID,\n type: 'line',\n layout: {\n 'line-join': 'round',\n 'line-cap': 'round',\n },\n paint: {\n 'line-color': SELECTED_COLOR,\n 'line-width': 2,\n },\n MAIN_LAYER_ID,\n });\n\n // layer for just the hovered feature\n map.addLayer({\n id: HOVERED_FEATURE_LAYER_ID,\n source: HOVERED_FEATURE_SOURCE_ID,\n type: 'fill',\n paint: {\n 'fill-antialias': false,\n 'fill-color': HOVERED_COLOR,\n 'fill-opacity': 0.2,\n },\n });\n\n // layer for hover & click interactions\n map.addLayer({\n id: INTERACTION_LAYER_ID,\n source: MAIN_SOURCE_ID,\n type: 'fill',\n paint: {\n // Don't show the fill, this layer is just for hover/click events.\n 'fill-opacity': 0,\n },\n });\n\n const onMouseMove = (e) => {\n const { id } = e.features[0].properties;\n // Don't highlight the feature if it's already selected\n if (id && !selectedFeatureIdsRef.current.includes(id)) {\n setHoveredFeatureId(id);\n } else {\n setHoveredFeatureId(null);\n }\n };\n\n const onMouseLeave = () => {\n setHoveredFeatureId(null);\n };\n\n const onClick = (e) => {\n // No interactions while drawing\n if (isDrawModeRef.current) return;\n\n const { id } = e.features[0].properties;\n\n // Don't let users deselect the fallback feature\n if (id === FALLBACK_FEATURE_ID) return;\n\n // clear the hover state temporarily so the user can see that they clicked on the feature\n setHoveredFeatureId(null);\n\n // toggle the feature's selected state\n toggleFeatureId(id);\n };\n\n map.on('mousemove', INTERACTION_LAYER_ID, onMouseMove);\n map.on('mouseleave', INTERACTION_LAYER_ID, onMouseLeave);\n map.on('click', INTERACTION_LAYER_ID, onClick);\n\n // cleanup\n return () => {\n if (!map || map._removed) return; // eslint-disable-line no-underscore-dangle\n\n map.off('mousemove', INTERACTION_LAYER_ID, onMouseMove);\n map.off('mouseleave', INTERACTION_LAYER_ID, onMouseLeave);\n map.off('click', INTERACTION_LAYER_ID, onClick);\n\n map.removeLayer(MAIN_LAYER_ID);\n map.removeLayer(SELECTED_FEATURES_LAYER_ID);\n map.removeLayer(HOVERED_FEATURE_LAYER_ID);\n map.removeLayer(INTERACTION_LAYER_ID);\n\n map.removeSource(MAIN_SOURCE_ID);\n map.removeSource(SELECTED_FEATURES_SOURCE_ID);\n map.removeSource(HOVERED_FEATURE_SOURCE_ID);\n };\n }, [\n mapRef, // (stable)\n selectedFeatureIdsRef, // (stable)\n isDrawModeRef, // (stable)\n toggleFeatureId, // (stable)\n ]);\n\n // When hoveredFeatureId changes, update the source for the hovered feature\n useEffect(() => {\n const map = mapRef.current;\n if (!map) return;\n\n const data = emptyFeature();\n if (hoveredFeatureId) {\n const hoveredFeatures = map.querySourceFeatures(MAIN_SOURCE_ID, {\n filter: ['==', 'id', hoveredFeatureId],\n });\n if (hoveredFeatures) data.features = hoveredFeatures;\n }\n\n map.getSource(HOVERED_FEATURE_SOURCE_ID).setData(data);\n }, [hoveredFeatureId, mapRef]);\n\n // When selectedFeatureIds changes, update the source for the selected features\n useEffect(() => {\n const map = mapRef.current;\n if (!map) return;\n\n const selectedFeatures = getSelectedFeatures(map, selectedFeatureIds);\n map\n .getSource(SELECTED_FEATURES_SOURCE_ID)\n .setData(featureCollection(selectedFeatures));\n }, [selectedFeatureIds, mapRef]);\n\n // When isDrawMode is true, hide some layers\n useEffect(() => {\n const map = mapRef.current;\n if (!map) return;\n\n const visibility = isDrawMode ? 'none' : 'visible';\n map.setLayoutProperty(HOVERED_FEATURE_LAYER_ID, 'visibility', visibility);\n map.setLayoutProperty(INTERACTION_LAYER_ID, 'visibility', visibility);\n }, [isDrawMode, mapRef]);\n\n return null;\n};\n\nexport default LandBoundariesLayer;\n","import { useState } from 'react';\nimport styled from 'styled-components';\nimport { Button, Input, Modal, ModalBody } from 'reactstrap';\nimport { Formik, Field, Form } from 'formik';\nimport { useWindowSize } from 'react-use';\n\nimport { BREAKPOINTS, BREAKPOINT_VALUES } from '../../../utils/responsive';\nimport { SIDE_PANEL_WIDTHS } from '../constants';\n\nconst Panel = styled.div`\n font-family: 'Lato', sans-serif;\n text-align: center;\n\n display: flex;\n flex-shrink: 0;\n flex-direction: column;\n justify-content: center;\n margin: 0 auto;\n\n padding: 8px;\n font-size: 13px;\n width: 100%;\n\n @media (min-width: ${BREAKPOINTS.md}) {\n padding: 16px;\n }\n\n @media (min-width: ${BREAKPOINTS.lg}) {\n font-size: 15.6px;\n padding: 24px;\n width: ${SIDE_PANEL_WIDTHS.lg};\n }\n`;\n\nconst SloganText = styled.div`\n font-weight: 600;\n color: #000000;\n\n margin: 0 auto 8px;\n\n font-size: 20px;\n\n @media (min-width: ${BREAKPOINTS.md}) {\n margin-bottom: 16px;\n font-size: 20px;\n }\n\n @media (min-width: ${BREAKPOINTS.lg}) {\n margin-bottom: 16px;\n font-size: 26px;\n }\n`;\n\nconst SubsloganText = styled.div`\n font-size: 15.6px;\n margin: 0 auto 12px;\n\n @media (min-width: ${BREAKPOINTS.lg}) {\n margin-bottom: 16px;\n }\n`;\n\nconst Highlighted = styled.span`\n background-color: #eefbe1;\n padding: 0 3px;\n white-space: nowrap;\n`;\n\nconst InputField = ({\n type,\n id,\n autoComplete,\n placeholder,\n required = false,\n}) => (\n \n);\n\nconst OnlyMobile = styled.div`\n display: block;\n @media (min-width: ${BREAKPOINTS.lg}) {\n display: none;\n }\n`;\n\nconst OnlyDesktop = styled.div`\n display: none;\n @media (min-width: ${BREAKPOINTS.lg}) {\n display: block;\n }\n`;\n\nconst Slogan = () => (\n \n Put the Right Trees
\n in the Right Places for the
\n Right Reason\n
\n);\n\nconst InboundForm = ({ onSubmit }) => {\n return (\n \n
\n \n Work with us to plan and plant your farmland.\n \n\n \n \n \n\n \n \n \n );\n};\n\n/**\n * Panel with the form and the call to action (CTA) button.\n */\nconst CTAPanel = ({ onSubmit }) => {\n const [modalIsOpen, setModalIsOpen] = useState(false);\n\n const windowWidth = useWindowSize(window.innerWidth).width;\n const isLargerScreen = windowWidth > BREAKPOINT_VALUES.lg;\n\n return (\n <>\n \n \n \n \n\n
\n \n \n \n\n \n {\n setModalIsOpen(true);\n }}\n >\n Get In Touch\n \n \n
\n
\n\n {\n setModalIsOpen(false);\n }}\n backdrop\n toggle={() => {\n setModalIsOpen((o) => !o);\n }}\n >\n \n \n \n \n \n \n );\n};\n\nexport default CTAPanel;\n","/**\n * Used on public routes to load the tileset metadata.\n *\n * NOTE: don't use this function unless you specifically need to load the\n * tileset metadata for non-authed users. For authed users, use the GraphQL\n * TilesetsQuery.\n */\nexport const loadTilesetsMetadata = async () => {\n const response = await fetch('/api/public/tileset_metadata');\n\n if (response.status !== 200) {\n const responseText = await response.text();\n throw new Error(responseText);\n }\n\n const json = await response.json();\n const { results, error } = json;\n\n if (!results || error) {\n throw new Error(error ?? 'Failed to fetch tilesets metadata');\n }\n\n return results;\n};\n","import * as turf from '@turf/turf';\n\nimport { MAPBOX_SOURCECACHE_LAYER_PREFIX } from '../../../constants/map';\nimport {\n getCalculateSuitabilityFromMap,\n getClippableTilesetLayers,\n} from './helpers';\n\n/**\n * Calculates suitability across multiple layers in the map. It returns a\n * mapping of layerIds to the number of suitable acres for each layer.\n *\n * It's a similar to `colorForLayerPoint`, but it calculates suitability across\n * many points on the map and across many layers (instead of just one point on\n * one layer).\n *\n * WARNING: this function uses internal Mapbox GL JS APIs.\n */\nconst suitabilityAcrossLayers = (map, layerIds, featureCollection) => {\n /* eslint-disable no-underscore-dangle */\n if (!map || !featureCollection?.features?.length || !layerIds?.length) {\n throw new Error('Invalid arguments');\n }\n\n const layers = getClippableTilesetLayers(map, layerIds);\n\n // Store init values so we can restore them at the end:\n const originalPosition = {\n center: map.getCenter(),\n zoom: map.getZoom(),\n pitch: map.getPitch(),\n };\n const originalUniformValues = Object.fromEntries(\n layers.map((layer) => [\n layer.implementation.id,\n {\n opacity: layer.implementation.opacity,\n fadeFactor: layer.implementation.fadeFactor,\n },\n ]),\n );\n\n // Adjust map center/zoom to fit the bounds of the featureCollection\n const bounds = turf.bbox(featureCollection);\n if (!bounds) {\n console.error(\"couldn't get bounds for featureCollection\");\n return null;\n }\n map.fitBounds(bounds, { padding: 10, animate: false }); // minimal padding needed for this\n\n // Get a fn that will calculate suitability from the map within `featureCollection`\n // NOTE: we call this here so that we only generate the points to sample once\n const calculateSuitabilityFromMap = getCalculateSuitabilityFromMap({\n map,\n featureCollection,\n });\n\n const getSuitabilityForLayer = (layer) => {\n const { painter } = map;\n const customLayer = layer.implementation;\n\n // Adjust the layer's settings so the layer is fully opaque and the filtered out colors are fully transparent\n customLayer.updateOpacity(1);\n customLayer.updateFadeFactor(1);\n\n // Clear the painter so we can just draw this one layer\n painter.context.viewport.set([0, 0, painter.width, painter.height]);\n painter.context.clear({\n color: 'rgba(0,0,0,0)',\n depth: 1,\n });\n painter.clearStencil();\n\n // Render the layer\n const sourceCacheKey = `${MAPBOX_SOURCECACHE_LAYER_PREFIX}${customLayer.source}`;\n const sourceCache = painter.style._sourceCaches[sourceCacheKey];\n if (!sourceCache) {\n console.error('no source cache found!');\n return null;\n }\n const coords = sourceCache.getVisibleCoordinates().slice().reverse();\n painter.renderPass = 'translucent';\n painter.renderLayer(painter, sourceCache, layer, coords);\n\n return calculateSuitabilityFromMap();\n };\n\n try {\n const suitabilityByLayerId = {};\n layers.forEach((layer) => {\n suitabilityByLayerId[layer.id] = getSuitabilityForLayer(layer);\n });\n\n return suitabilityByLayerId;\n } catch (err) {\n console.error(err);\n return null;\n } finally {\n // Reset the map position\n map.setCenter(originalPosition.center, { animate: false });\n map.setZoom(originalPosition.zoom, { animate: false });\n map.setPitch(originalPosition.pitch, { animate: false });\n\n // Reset the opacities\n layers.forEach((layer) => {\n const { opacity, fadeFactor } = originalUniformValues[layer.id];\n layer.implementation.updateOpacity(opacity);\n layer.implementation.updateFadeFactor(fadeFactor);\n });\n\n // Repaint the map so the user doesn't see our render\n map.triggerRepaint();\n }\n /* eslint-enable no-underscore-dangle */\n};\n\nexport default suitabilityAcrossLayers;\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport _ from 'lodash';\nimport * as turf from '@turf/turf';\nimport MapboxDraw from '@mapbox/mapbox-gl-draw';\nimport { useLatest } from 'react-use';\n\nimport { loadTilesetsMetadata } from '../../utils/loadTilesetsMetadata';\nimport { TILESET_RASTER_OPACITY } from '../../constants/map';\nimport { useToggleMap } from '../../hooks/useToggleMap';\nimport { TILESET_LAYER_PREFIX } from '../../constants/tilesets';\nimport { layerIdForTileset } from '../../utils/tilesets';\nimport {\n DRAWN_FEATURE_ID_PREFIX,\n INIT_SELECTED_FEATURE_IDS_STATE,\n LOADING_MESSAGES,\n LOADING_MESSAGE_DURATION,\n TILESET_SPEC,\n} from './constants';\nimport { getSelectedFeatures, layerForTileset } from './helpers';\nimport suitabilityAcrossLayers from '../../utils/webgl/suitability-calculations/suitabilityAcrossLayers';\n\n/**\n * Disables pinch zoom for whole page.\n */\nexport const useDisablePageZoom = () => {\n useEffect(() => {\n const tag = document.querySelector('meta[name=\"viewport\"]');\n if (!tag) return null;\n\n const initValue = tag.getAttribute('content');\n\n tag.setAttribute(\n 'content',\n 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0',\n );\n\n return () => {\n tag.setAttribute('content', initValue);\n };\n }, []);\n};\n\n/**\n * Load the tileset metadata.\n */\nexport const useTilesetsData = () => {\n const [tilesets, setTilesets] = useState([]);\n useEffect(() => {\n (async () => {\n const fetchedData = await loadTilesetsMetadata();\n\n const tilesetSpecWithData = TILESET_SPEC.map((spec) => {\n const tilesetData = (fetchedData ?? []).find(\n (tileset) => tileset.name === spec.name,\n );\n return (\n tilesetData && {\n ...spec,\n ...tilesetData,\n }\n );\n }).filter(Boolean);\n\n setTilesets(tilesetSpecWithData);\n })();\n }, []);\n\n return tilesets;\n};\n\n/**\n * When selectedTilesetId changes, update the visibility of the tileset layers.\n */\nexport const useUpdateTilesetVisibility = (\n map,\n tilesets,\n selectedTilesetId,\n shouldShowTileset,\n) => {\n useEffect(() => {\n if (!map) return;\n\n if (selectedTilesetId) {\n // Make selected tileset layer visible\n const selectedLayer = layerForTileset(map, selectedTilesetId);\n\n if (selectedLayer) {\n selectedLayer.updateOpacity(\n // but don't show the tileset if no land boundaries are selected\n shouldShowTileset ? TILESET_RASTER_OPACITY : 0,\n );\n }\n }\n\n // Hide other tileset layers\n tilesets\n .filter(({ id }) => id !== selectedTilesetId)\n .forEach(({ id }) => {\n const layer = layerForTileset(map, id);\n if (layer) layer.updateOpacity(0);\n });\n\n map.triggerRepaint();\n }, [map, selectedTilesetId, shouldShowTileset, tilesets]);\n};\n\n/**\n * Manages state for the selected CLU boundary regions.\n */\nexport const useSelectedFeatures = (mapRef) => {\n const [userHasSelectedAFeature, setUserHasSelectedAFeature] = useState(false);\n\n const {\n state: featureSelectionMap,\n toggle: toggleFeatureId,\n reset: resetSelectedFeatures,\n setState: setFeatureSelectionMap,\n } = useToggleMap(INIT_SELECTED_FEATURE_IDS_STATE);\n\n const selectedFeatureIds = useMemo(\n () =>\n Object.entries(featureSelectionMap)\n .filter(([, value]) => value)\n .map(([key]) => key),\n [featureSelectionMap],\n );\n\n const [selectedFeatures, setSelectedFeatures] = useState([]);\n const selectedFeatureIdsRef = useLatest(selectedFeatureIds);\n const updateSelectedFeatures = useCallback(() => {\n const features = mapRef.current\n ? getSelectedFeatures(mapRef.current, selectedFeatureIdsRef.current)\n : [];\n setSelectedFeatures(features);\n }, [mapRef, selectedFeatureIdsRef]);\n\n useEffect(updateSelectedFeatures, [\n updateSelectedFeatures,\n selectedFeatureIds,\n ]);\n\n // Update the `userHasSelectedAFeature` tracker when the user does that for the first time\n useEffect(() => {\n if (selectedFeatureIds.length > 0 && !userHasSelectedAFeature) {\n setUserHasSelectedAFeature(true);\n }\n }, [selectedFeatureIds, userHasSelectedAFeature]);\n\n const setSelectedFeatureIds = useCallback(\n (ids) => {\n setFeatureSelectionMap(Object.fromEntries(ids.map((id) => [id, true])));\n },\n [setFeatureSelectionMap],\n );\n\n return {\n toggleFeatureId,\n resetSelectedFeatures,\n selectedFeatureIds,\n selectedFeatures,\n userHasSelectedAFeature,\n updateSelectedFeatures,\n setSelectedFeatureIds,\n };\n};\n\nexport const useCluLoading = () => {\n const [loadingMessageIndex, setLoadingMessageIndex] = useState(0); // an index into the LOADING_MESSAGES array\n const loadingMessage = LOADING_MESSAGES[loadingMessageIndex] ?? '';\n\n const cluLoadingInterval = useRef(null);\n\n const setCluLoading = useCallback(() => {\n if (cluLoadingInterval.current) clearInterval(cluLoadingInterval.current);\n\n setLoadingMessageIndex(1);\n cluLoadingInterval.current = setInterval(() => {\n setLoadingMessageIndex((x) => {\n if (x + 1 > LOADING_MESSAGES.length - 1) return x;\n return x + 1;\n });\n }, LOADING_MESSAGE_DURATION);\n }, []);\n\n const setCluNotLoading = useCallback(() => {\n if (cluLoadingInterval.current) {\n clearInterval(cluLoadingInterval.current);\n cluLoadingInterval.current = null;\n }\n setLoadingMessageIndex(0);\n }, []);\n\n return [loadingMessage, setCluLoading, setCluNotLoading];\n};\n\nexport const useSuitabilityPerCrop = (map, tilesets, selectedFeatures) => {\n const [suitabilityPerCrop, setSuitabilityPerCrop] = useState({});\n\n useEffect(() => {\n if (!map) return null;\n\n // Throttle this function to avoid a bunch of calculations in a row when all the tilesets load\n const calculateSuitability = _.throttle(() => {\n if (!map) return;\n\n if (tilesets.length === 0 || selectedFeatures.length === 0) {\n setSuitabilityPerCrop({});\n return;\n }\n\n const suitabilityByLayerId = suitabilityAcrossLayers(\n map,\n tilesets.map((t) => layerIdForTileset(t.id)),\n turf.featureCollection(selectedFeatures),\n );\n\n const newSuitabilityPerCrop = Object.fromEntries(\n tilesets\n .map(({ id, name, displayName }) => {\n const suitableAcres = Math.round(\n suitabilityByLayerId[layerIdForTileset(id)],\n );\n return [name, { name, displayName, suitableAcres }];\n })\n .filter(Boolean),\n );\n\n setSuitabilityPerCrop(newSuitabilityPerCrop);\n }, 250);\n\n // When selected features change, recalculate suitability per crop\n calculateSuitability();\n\n // When new tileset data loads, recalculate suitability per crop\n const onSourceData = ({ tile, sourceId, isSourceLoaded }) => {\n if (\n !tile ||\n !sourceId.startsWith(TILESET_LAYER_PREFIX) ||\n !isSourceLoaded\n ) {\n return;\n }\n calculateSuitability();\n };\n map.on('sourcedata', onSourceData);\n return () => {\n map.off('sourcedata', onSourceData);\n };\n }, [map, selectedFeatures, tilesets]);\n\n return suitabilityPerCrop;\n};\n\nexport const useDrawMode = ({ map, setLayerData: setLayerDataFn }) => {\n const setLayerDataRef = useLatest(setLayerDataFn); // wrap in a ref so we can use it in event handlers\n\n // NOTE: `isDrawMode` means that the draw mode is active, not that the user is currently drawing\n const [isDrawMode, setIsDrawMode] = useState(false);\n\n // NOTE: `isDrawing` means that the user is currently drawing (vs selecting).\n const [isDrawing, setIsDrawing] = useState(false);\n\n const mapboxDrawRef = useRef(null);\n\n const [selectedFeatureId, setSelectedFeatureId] = useState(null);\n const featureIsSelected = !!selectedFeatureId;\n\n // Reset selectedFeatureId when exiting draw mode\n if (!isDrawMode && selectedFeatureId) {\n setSelectedFeatureId(null);\n }\n\n const NON_DRAWN_FEATURE_ID_PREFIX = 'non-drawn-feature-';\n\n const drawPolygon = () => {\n const mapboxDraw = mapboxDrawRef.current;\n if (!map || !mapboxDraw || !isDrawMode) return;\n\n setIsDrawing(true);\n mapboxDraw.changeMode('draw_polygon');\n };\n\n const deleteFeature = async () => {\n const setLayerData = setLayerDataRef.current;\n\n const mapboxDraw = mapboxDrawRef.current;\n if (!map || !mapboxDraw || !isDrawMode) return;\n\n if (!selectedFeatureId) return;\n\n // Remove the feature from the mapbox draw layer\n const mapboxDrawFeatures = mapboxDraw.getAll().features;\n const mapboxDrawFeature = mapboxDrawFeatures.find(\n (f) => f.properties.id === selectedFeatureId,\n );\n if (mapboxDrawFeature) {\n mapboxDraw.delete(mapboxDrawFeature.id);\n }\n\n // Remove the feature from the map\n setLayerData((data) => {\n const filteredFeatures = data.features.filter(\n (f) => f.properties.id !== selectedFeatureId,\n );\n return { ...data, features: filteredFeatures };\n }); // (we don't await here -- that way, the user can continue drawing while the map updates)\n\n // If there are no features left, go back to draw mode\n if (mapboxDraw.getAll().features.length === 0) {\n drawPolygon();\n }\n\n setSelectedFeatureId(null);\n };\n\n const deleteAll = () => {\n const setLayerData = setLayerDataRef.current;\n\n const mapboxDraw = mapboxDrawRef.current;\n if (!map || !mapboxDraw || !isDrawMode) return;\n\n // remove all features from the mapbox draw layer\n mapboxDraw.deleteAll();\n\n // remove all features from the map\n setLayerData(() => turf.featureCollection([]));\n\n // go back to draw mode\n drawPolygon();\n };\n\n useEffect(() => {\n const setLayerData = setLayerDataRef.current;\n\n if (!map || !isDrawMode) return null;\n\n const mapboxDraw = new MapboxDraw({\n displayControlsDefault: false,\n defaultMode: 'draw_polygon',\n });\n mapboxDrawRef.current = mapboxDraw;\n map.addControl(mapboxDraw);\n setIsDrawing(true);\n\n // Update map data as user edits features:\n const updateData = () => {\n const data = mapboxDraw.getAll();\n\n // Add IDs to the features\n const dataWithIds = { ...data };\n dataWithIds.features = data.features.map((feature) => {\n // ensure ids are unique and have the prefix\n let { id } = feature.properties;\n if (\n !id ||\n (!id.startsWith(DRAWN_FEATURE_ID_PREFIX) &&\n !id.startsWith(NON_DRAWN_FEATURE_ID_PREFIX))\n ) {\n id = _.uniqueId(DRAWN_FEATURE_ID_PREFIX);\n }\n\n // make sure mapbox draw has the id as well\n mapboxDraw.setFeatureProperty(feature.id, 'id', id);\n\n return {\n ...feature,\n id,\n properties: {\n ...feature.properties,\n id,\n },\n };\n });\n\n setLayerData(() => dataWithIds);\n };\n\n // Keep user in draw mode after they finish drawing a feature (?)\n const onSelectionChange = ({ features }) => {\n const [feature] = features;\n setSelectedFeatureId(feature?.properties?.id ?? null);\n };\n const onModeChange = ({ mode }) => {\n setIsDrawing(mode.startsWith('draw'));\n };\n\n map.on('draw.selectionchange', onSelectionChange);\n map.on('draw.create', updateData);\n map.on('draw.update', updateData);\n map.on('draw.modechange', onModeChange);\n\n return () => {\n if (map._removed) return; // eslint-disable-line no-underscore-dangle\n\n mapboxDraw.deleteAll();\n\n map.removeControl(mapboxDraw);\n\n map.off('draw.selectionchange', onSelectionChange);\n map.off('draw.create', updateData);\n map.off('draw.update', updateData);\n map.off('draw.modechange', onModeChange);\n\n mapboxDrawRef.current = null;\n setIsDrawing(false);\n };\n }, [map, isDrawMode, setLayerDataRef]);\n\n return {\n isDrawMode,\n setIsDrawMode,\n featureIsSelected,\n isDrawing,\n deleteFeature,\n deleteAll,\n drawPolygon,\n };\n};\n","import styled from 'styled-components';\n\nimport { ResponsiveButton } from './basic';\n\nconst DEFAULT_BACKGROUND = '#efefef';\nconst HOVER_BACKGROUND = '#dcdcdc';\nconst SELECTED_BACKGROUND = '#395535';\n\nconst SELECTED_CLASS = 'active';\n\nconst makeGreenButton = (Component) => styled(Component)`\n border: none !important;\n\n color: #000 !important;\n background-color: ${DEFAULT_BACKGROUND} !important;\n\n &:hover {\n background-color: ${HOVER_BACKGROUND} !important;\n }\n\n &.${SELECTED_CLASS} {\n color: #fff !important;\n background-color: ${SELECTED_BACKGROUND} !important;\n }\n`;\n\nconst ResponsiveGreenButtonComponent = makeGreenButton(ResponsiveButton);\n\n/**\n * `GreenButton` that is responsive to screen size, via `ResponsiveButton`.\n */\nexport const GreenButton = ({ active, sizes = ['sm'], ...props }) => (\n \n);\n","import styled from 'styled-components';\nimport { CROP_INFOS } from '../constants';\nimport { BREAKPOINTS } from '../../../utils/responsive';\n\nconst Container = styled.div`\n height: fit-content;\n color: #000;\n\n padding: 0 6px;\n font-size: 12px;\n @media (min-width: ${BREAKPOINTS.xs}) {\n padding: 0 8px;\n font-size: 13px;\n }\n @media (min-width: ${BREAKPOINTS.md}) {\n padding: 0 12px;\n font-size: 15.6px;\n }\n`;\n\nconst CropInfo = ({ currentCropName }) => {\n const { description = null } = CROP_INFOS[currentCropName] ?? {};\n return {description};\n};\n\nexport default CropInfo;\n","import { useMemo, useState } from 'react';\nimport styled from 'styled-components';\nimport * as turf from '@turf/turf';\nimport { Button } from 'reactstrap';\nimport { useWindowSize } from 'react-use';\n\nimport { InfoCard, LinkNewTab } from './basic';\nimport { GreenButton } from './GreenButton';\nimport SectionsIcon from '../../icons/SectionsIcon';\nimport CropIcon from '../../icons/CropIcon';\nimport SuitabilityIcon from '../../icons/SuitabilityIcon';\nimport { acresPerSqMeter } from '../../../constants/units';\nimport {\n BREAKPOINTS,\n BREAKPOINT_VALUES,\n useIsMobile,\n} from '../../../utils/responsive';\nimport {\n FALLBACK_FEATURE_ID,\n SIDE_PANEL_WIDTHS,\n SUITABILITY_INPUTS,\n} from '../constants';\nimport CropInfo from './CropInfo';\nimport { captureEvent } from '../../../utils/analytics';\nimport { unitForValue } from '../../../utils/formatters';\nimport { sortTilesetSuitability } from '../helpers';\nimport PositionedOverMap from '../../basics/PositionedOverMap';\n\nconst Container = styled(InfoCard)`\n display: flex;\n\n font-size: 13px;\n max-width: calc(100vw - 16px);\n\n @media (min-width: ${BREAKPOINTS.md}) {\n font-size: 15.6px;\n }\n\n @media (min-width: ${BREAKPOINTS.lg}) {\n max-width: calc(100vw - ${SIDE_PANEL_WIDTHS.lg} - 32px);\n }\n`;\n\nconst Header = styled.div`\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n padding-bottom: 8px;\n margin-bottom: 8px;\n border-bottom: 1px solid #dee2e6;\n\n font-size: 12px;\n @media (min-width: ${BREAKPOINTS.xs}) {\n font-size: 13px;\n }\n @media (min-width: ${BREAKPOINTS.md}) {\n font-size: 15.6px;\n }\n`;\n\nconst Body = styled.div`\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n\n height: 300px;\n padding: 8px;\n\n /* Prevent this from covering up too much of the map on mobile */\n max-height: calc((100vh - 160px) / 2);\n min-height: 100px;\n overflow: auto;\n\n @media (min-width: ${BREAKPOINTS.md}) {\n height: 330px;\n\n padding: 12px 16px 12px 12px;\n\n max-height: unset;\n min-height: unset;\n overflow-y: unset;\n }\n`;\n\nconst CropSuitabilityContainer = styled.div`\n max-width: 536px;\n`;\n\nconst CropInfoContainer = styled.div`\n max-width: 536px;\n`;\n\nconst SuitabilityInfoContainer = styled.div`\n max-width: 536px;\n`;\n\nconst CropInfoSection = styled.div`\n flex-grow: 1;\n display: flex;\n\n max-height: 300px;\n overflow: auto;\n`;\n\nconst CropSelectorContainer = styled.div`\n flex-shrink: 1;\n margin-right: 8px;\n\n @media (min-width: ${BREAKPOINTS.xs}) {\n flex-shrink: 0;\n }\n\n @media (min-width: ${BREAKPOINTS.sm}) {\n margin-right: 16px;\n }\n`;\n\nconst Row = styled.div`\n :not(:last-child) {\n margin-bottom: 6px;\n }\n\n @media (min-width: ${BREAKPOINTS.md}) {\n :not(:last-child) {\n margin-bottom: 8px;\n }\n }\n`;\n\nconst TABS = {\n ACRES: 'SUITABLE_ACRES',\n CROPS: 'CROPS',\n METHODOLOGY: 'SUITABILITY_OVERVIEW',\n};\n\nconst TabButton = ({ tab, currentTab, setTab }) => {\n const methodologyTitle =\n useWindowSize().width < BREAKPOINT_VALUES.md ? 'Method' : 'Methodology';\n\n const text = {\n [TABS.ACRES]: 'Suitability',\n [TABS.CROPS]: 'Crop Info',\n [TABS.METHODOLOGY]: methodologyTitle,\n }[tab];\n\n const Icon = {\n [TABS.ACRES]: SectionsIcon,\n [TABS.CROPS]: CropIcon,\n [TABS.METHODOLOGY]: SuitabilityIcon,\n }[tab];\n\n return (\n {\n captureEvent('suitability_tool_tab_click', { tab });\n setTab(tab);\n }}\n active={tab === currentTab}\n >\n
{text}
\n
\n \n
\n \n );\n};\n\nconst CropSelector = ({\n sortedTilesetsWithSuitability,\n selectTileset,\n selectedTilesetId,\n showSuitableAcres = false,\n}) => {\n return sortedTilesetsWithSuitability.map(\n ({ id, name, displayName, suitableAcres }) => {\n const acresToShow = showSuitableAcres && suitableAcres;\n\n return (\n \n {\n selectTileset(name, { userAction: true });\n }}\n active={id === selectedTilesetId}\n >\n {displayName}\n \n\n {/* Don't show suitable acres if the data hasn't loaded yet or if it's 0 */}\n {!!acresToShow && (\n
\n {acresToShow} suitable{' '}\n {unitForValue('acres', 'acre')(acresToShow)}\n
\n )}\n \n );\n },\n );\n};\n\nconst SuitableAcresTab = ({\n sortedTilesetsWithSuitability,\n selectTileset,\n selectedTilesetId,\n}) => (\n \n
\n Preview suitability for sample crops on your land by selecting the crops\n below\n
\n \n
\n);\n\nconst CropInfoTab = ({\n sortedTilesetsWithSuitability,\n selectTileset,\n selectedTilesetId,\n}) => {\n const selectedTilesetName = useMemo(\n () =>\n sortedTilesetsWithSuitability.find(({ id }) => id === selectedTilesetId)\n ?.name,\n [sortedTilesetsWithSuitability, selectedTilesetId],\n );\n\n return (\n \n \n \n \n \n \n \n \n );\n};\n\nconst SuitabilityInput = styled.div`\n display: grid;\n grid-template-columns: 1fr 1fr;\n\n font-size: 10px;\n grid-gap: 8px;\n margin-bottom: 12px;\n\n @media (min-width: ${BREAKPOINTS.xs}) {\n grid-template-columns: 1fr 1fr 1fr;\n font-size: 13px;\n }\n @media (min-width: ${BREAKPOINTS.sm}) {\n font-size: 15.6px;\n }\n\n @media (min-width: ${BREAKPOINTS.md}) {\n grid-gap: 12px;\n margin-bottom: 16px;\n }\n\n > div {\n border-radius: 3px;\n color: var(--text-color);\n background-color: var(--border-color);\n text-align: center;\n\n padding: 4px;\n\n @media (min-width: ${BREAKPOINTS.sm}) {\n padding: 4px 8px;\n }\n }\n`;\n\nconst SuitabilityInfoTab = () => {\n return (\n \n \n {SUITABILITY_INPUTS.map((inputName) => (\n
{inputName}
\n ))}\n
\n
\n
\n Propagate's crop suitability model is based on crop adaptation to\n 12 environmental factors. Reach out for expert support and access to\n our detailed crop suitability analytics for dozens of tree crops.{' '}\n \n Learn More\n \n
\n \n Disclamer: crop suitability maps are not a recommendation by Propagate\n Group or Overyield. The Information is provided without representation\n or warranty of any kind. All farms should have proper site diligence\n performed to validate on the ground conditions prior to selecting a\n crop. The accuracy of the underlying data will vary by location as we\n improve data availability & the suitability algorithms.\n \n
\n
\n );\n};\n\nconst InfoPanel = ({\n tilesets,\n suitabilityPerCrop,\n selectedTilesetId,\n selectTileset,\n selectedFeatures,\n reset,\n isDrawMode,\n}) => {\n const [tab, setTab] = useState(TABS.ACRES);\n\n const isMobile = useIsMobile();\n\n const tilesetsWithSuitability = tilesets.map((tileset) => ({\n ...tileset,\n ...suitabilityPerCrop[tileset.name],\n }));\n\n const selectedFeaturesCount = selectedFeatures.length;\n const selectedFeaturesArea = useMemo(\n () =>\n selectedFeatures.length > 0\n ? Math.round(\n turf.area(turf.featureCollection(selectedFeatures)) *\n acresPerSqMeter,\n )\n : 0,\n [selectedFeatures],\n );\n\n const selectedFeatureIsFallback =\n selectedFeatures.length === 1 &&\n selectedFeatures[0].id === FALLBACK_FEATURE_ID;\n\n const sortedTilesetsWithSuitability = sortTilesetSuitability(\n tilesetsWithSuitability,\n );\n\n const windowWidth = useWindowSize().width;\n\n if (selectedFeaturesCount === 0) {\n // Ensure that the info box is not blocking things on smaller screens\n const style =\n windowWidth < BREAKPOINT_VALUES.xl ? { marginTop: '80px' } : {};\n\n return (\n \n \n
\n {isDrawMode\n ? 'Draw your land parcels on the map.'\n : `Select the regions of your farm by ${\n isMobile ? 'tapping' : 'clicking on'\n } the map.`}\n
\n
\n
\n );\n }\n\n return (\n \n \n
\n {/* TAB SELECTORS */}\n \n \n \n
\n\n \n {/* TAB CONTENT */}\n {tab === TABS.ACRES && (\n \n )}\n {tab === TABS.CROPS && (\n \n )}\n {tab === TABS.METHODOLOGY && }\n\n {/* Don't show parcel meta if it's just the fallback feature: */}\n {!selectedFeatureIsFallback && (\n
\n
\n {selectedFeaturesCount}{' '}\n {unitForValue('parcels', 'parcel')(selectedFeaturesCount)},{' '}\n {selectedFeaturesArea}{' '}\n {unitForValue('acres', 'acre')(selectedFeaturesArea)} selected.\n
\n\n {selectedFeaturesCount > 0 && (\n <>\n \n Reset\n \n .\n \n )}\n
\n )}\n \n
\n
\n );\n};\n\nexport default InfoPanel;\n","import styled from 'styled-components';\nimport { Button } from 'reactstrap';\n\nimport { MainContainer } from './basic';\n\nconst PostSubmitMessage = styled.div`\n font-size: 20px;\n`;\n\nconst PostSubmit = () => (\n \n
\n \n\n \n Thanks! A member of our team will be in touch soon.\n \n\n \n Propagate Homepage\n \n\n {\n window.location.reload();\n }}\n >\n Back\n \n
\n
\n);\n\nexport default PostSubmit;\n","export const submitMarketingInbound = async ({\n name,\n email,\n phone,\n address,\n coordinates,\n lastSelectedCrop,\n allViewedCrops,\n suitabilitySummary,\n}) => {\n const response = await fetch('/api/public/submit_marketing_inbound', {\n body: JSON.stringify({\n name: name ?? '',\n email: email ?? '',\n phone: phone ?? '',\n address: address ?? '',\n coordinates: coordinates ?? '',\n lastSelectedCrop: lastSelectedCrop ?? '',\n allViewedCrops: allViewedCrops ?? '',\n suitabilitySummary: suitabilitySummary ?? '',\n }),\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (response.status !== 200) {\n const responseText = await response.text();\n throw new Error(responseText);\n }\n\n const json = await response.json();\n const { results, error } = json;\n\n if (!results || error) {\n throw new Error(error ?? 'Failed to submit marketing inbound.');\n }\n\n return results;\n};\n","import { useMemo } from 'react';\nimport { useLatest } from 'react-use';\n\nimport { asSequentialAsync } from '../utils/async';\n\n/**\n * React hook version of `asSequentialAsync`. This hook returns an async\n * function that can be invoked multiple times in parallel, but will ensure that\n * the invocations are processed one at a time, in order.\n *\n * NOTE: `fn` must be stable (memoized/constant/similar) since the returned\n * wrapped function is only created once.\n */\nconst useAsSequentialAsync = (fn) => {\n const fnRef = useLatest(fn); // Wrap in a ref to ensure the useMemo below is only evaluated once\n return useMemo(() => asSequentialAsync(fnRef.current), [fnRef]);\n};\n\nexport default useAsSequentialAsync;\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { Button, Spinner } from 'reactstrap';\nimport * as turf from '@turf/turf';\nimport { featureCollection } from '@turf/turf';\nimport { useEffectOnce } from 'react-use';\n\nimport MapContainer from '../map/MapContainer';\nimport NaipLayer from '../map/NaipLayer';\nimport useInitializeMapEffect from '../../hooks/useInitializeMapEffect';\nimport {\n addReferenceLayers,\n forceMapResize,\n getSourceData,\n setSourceData,\n} from '../../utils/map';\nimport { captureEvent } from '../../utils/analytics';\nimport LandBoundariesLayer from './components/LandBoundariesLayer';\nimport AddressSearch from './components/AddressSearch';\nimport CTAPanel from './components/CTAPanel';\nimport Logo from '../icons/Logo';\nimport ChevronIcon from '../icons/ChevronIcon';\nimport {\n addFallbackBoundary,\n getNonFallbackFeatures,\n layerForTileset,\n loadCluToMapWithTimeout,\n sortTilesetSuitability,\n} from './helpers';\nimport {\n useCluLoading,\n useDisablePageZoom,\n useDrawMode,\n useSelectedFeatures,\n useSuitabilityPerCrop,\n useTilesetsData,\n useUpdateTilesetVisibility,\n} from './hooks';\nimport {\n DemoMapBackground,\n FullOverlay,\n InfoText,\n LoadingCard,\n MainContainer,\n PromptCard,\n ResponsiveButton,\n} from './components/basic';\nimport {\n DRAWN_FEATURE_ID_PREFIX,\n INIT_MAP_POSITION,\n MAIN_SOURCE_ID,\n STEPS,\n} from './constants';\nimport InfoPanel from './components/InfoPanel';\nimport PostSubmit from './components/PostSubmit';\nimport { submitMarketingInbound } from '../../utils/submitMarketingInbound';\nimport { emptyFeature } from '../../utils/geojson';\nimport useAsSequentialAsync from '../../hooks/useAsSequentialAsync';\nimport PositionedOverMap from '../basics/PositionedOverMap';\nimport useAddClippableTilesetLayers from '../../hooks/useAddClippableTilesetLayers';\n\nconst PublicSuitabilityTool = () => {\n // No zoom on mobile:\n useDisablePageZoom();\n\n // Map state\n const mapContainer = useRef(null);\n const mapRef = useRef(null);\n const [mapLoaded, setMapLoaded] = useState(false);\n const loadedMap = mapLoaded && mapRef.current;\n\n // Initialize the map\n useInitializeMapEffect({\n mapContainer,\n mapRef,\n mapLoaded,\n setMapLoaded,\n onLoad: () => {\n addReferenceLayers(mapRef.current);\n },\n ...INIT_MAP_POSITION,\n controls: {\n geolocation: false,\n compass: false,\n fullscreen: false,\n },\n });\n\n // Track page state (step)\n const [step, setStep] = useState(STEPS.INPUT_ADDRESS);\n\n // Analytics\n useEffectOnce(() => {\n captureEvent('public-suitability-tool-started');\n });\n useEffect(() => {\n captureEvent('public-suitability-tool-step', { step });\n }, [step]);\n\n // Fix issue where canvas doesn't resize properly\n useEffect(() => {\n forceMapResize();\n }, [step]);\n\n // Load tilesets & add to map\n const tilesets = useTilesetsData();\n useAddClippableTilesetLayers(loadedMap, tilesets);\n\n // State for selected tileset\n const [selectedTilesetId, setSelectedTilesetId] = useState(null);\n const selectTileset = useCallback(\n (name) => {\n const id = tilesets.find((tileset) => tileset.name === name)?.id;\n setSelectedTilesetId(id ?? null);\n captureEvent('public-suitability-tool-tileset-selected', { name });\n },\n [tilesets],\n );\n\n // State for selected CLU boundary regions\n const {\n toggleFeatureId,\n resetSelectedFeatures,\n selectedFeatureIds,\n selectedFeatures,\n userHasSelectedAFeature,\n updateSelectedFeatures,\n setSelectedFeatureIds,\n } = useSelectedFeatures(mapRef);\n\n // This function sets the data for the main source and updates the selected\n // features. To avoid race conditions, we use `asSequentialAsync`, which\n // ensures that although the function may be called multiple times in quick\n // succession, each call will be processed one at a time, in order.\n //\n // `transformData` should accept a FeatureCollection and return a FeatureCollection.\n const setLayerData = useAsSequentialAsync(async (transformData) => {\n const map = mapRef.current;\n if (!map) return;\n\n // Get existing data and transform it with `transformData`\n const existing = getSourceData(map, MAIN_SOURCE_ID);\n const data = transformData(turf.featureCollection(existing));\n\n // Set the transformed data\n await setSourceData(map, MAIN_SOURCE_ID, data);\n\n // Select all drawn features\n const newFeatureIds = data.features\n .map(({ properties: { id } }) => id)\n .filter((id) => id.startsWith(DRAWN_FEATURE_ID_PREFIX));\n setSelectedFeatureIds(newFeatureIds);\n });\n\n // DRAW MODE\n const {\n isDrawMode,\n setIsDrawMode,\n featureIsSelected: drawModeFeatureIsSelected,\n isDrawing,\n deleteFeature: deleteSelectedDrawnFeature,\n deleteAll: deleteAllDrawnFeatures,\n drawPolygon,\n } = useDrawMode({\n map: loadedMap,\n setLayerData,\n });\n\n const infoPanelResetHandler = () => {\n if (isDrawMode) deleteAllDrawnFeatures();\n else resetSelectedFeatures();\n };\n\n // When selectedTilesetId changes, update the visibility of the tileset layers\n const shouldShowTileset = selectedFeatureIds.length > 0;\n useUpdateTilesetVisibility(\n loadedMap,\n tilesets,\n selectedTilesetId,\n shouldShowTileset,\n );\n\n // When selectedFeatures changes, update the raster layers' masks\n useEffect(() => {\n const map = mapRef.current;\n if (!map) return;\n\n // Update the layers with their updateMask method\n tilesets.forEach(({ id }) => {\n const layer = layerForTileset(map, id);\n if (layer) layer.updateMask(selectedFeatures);\n });\n }, [selectedFeatures, tilesets]);\n\n // Calculate suitability per crop\n const suitabilityPerCrop = useSuitabilityPerCrop(\n loadedMap,\n tilesets,\n selectedFeatures,\n );\n\n // When suitability per crop changes, if no tileset selected, select the most suitable crop\n useEffect(() => {\n if (selectedTilesetId) return;\n\n const crops = Object.values(suitabilityPerCrop);\n if (crops.length === 0) return;\n\n const [max] = sortTilesetSuitability(crops);\n if (!max) return;\n\n const { name: mostSuitableCrop, suitableAcres: acresForCrop } = max;\n if (acresForCrop) selectTileset(mostSuitableCrop);\n }, [selectedTilesetId, suitabilityPerCrop, selectTileset]);\n\n // Tracks if the CLU data is loading\n const [loadingMessage, setCluLoading, setCluNotLoading] = useCluLoading();\n\n // Load CLU boundaries when on LOADING_BOUNDARIES step\n useEffect(() => {\n const map = mapRef.current;\n if (!map) return;\n\n if (step === STEPS.LOADING_BOUNDARIES) {\n setCluLoading();\n\n (async () => {\n try {\n await loadCluToMapWithTimeout(mapRef);\n setStep(STEPS.SELECT_REGIONS);\n } catch (err) {\n console.error(err);\n setStep(STEPS.BOUNDARY_LOAD_FAILURE);\n } finally {\n setCluNotLoading();\n }\n })();\n }\n }, [\n step,\n // All stable:\n selectTileset,\n setCluLoading,\n setCluNotLoading,\n toggleFeatureId,\n resetSelectedFeatures,\n ]);\n\n /**\n * Data to submit for inbound lead:\n * - address {string}\n * - coordinates {string}\n * - lastSelectedCrop {string}\n * - allViewedCrops {Set}\n * - suitabilitySummary {string}\n *\n * Note: name/email/phone are passed in from the CTAPanel and arent stored in this ref.\n */\n const dataToSubmitRef = useRef({});\n\n // Update dataToSubmitRef when selectedTilesetId changes\n useEffect(() => {\n if (selectedTilesetId && tilesets) {\n const tileset = tilesets.find((t) => t.id === selectedTilesetId);\n if (tileset) {\n dataToSubmitRef.current.lastSelectedCrop = tileset.displayName;\n\n if (dataToSubmitRef.current.allViewedCrops === undefined) {\n dataToSubmitRef.current.allViewedCrops = new Set();\n }\n dataToSubmitRef.current.allViewedCrops.add(tileset.displayName);\n }\n }\n }, [selectedTilesetId, tilesets]);\n\n // Update dataToSubmitRef when suitabilityPerCrop changes\n useEffect(() => {\n if (suitabilityPerCrop) {\n const cropsWithSuitability = Object.values(suitabilityPerCrop).filter(\n (crop) => crop.suitableAcres > 0,\n );\n\n dataToSubmitRef.current.suitabilitySummary = cropsWithSuitability\n .map(\n ({ displayName, suitableAcres }) =>\n `${displayName}: ${suitableAcres.toFixed(1)} acres`,\n )\n .join('\\n');\n }\n }, [suitabilityPerCrop]);\n\n const submitInbound = async ({ name, email, phone }) => {\n try {\n const {\n address,\n coordinates,\n lastSelectedCrop,\n allViewedCrops: allViewedCropsSet,\n suitabilitySummary,\n } = dataToSubmitRef.current;\n const allViewedCrops = [...(allViewedCropsSet ?? [])].join('\\n');\n\n await submitMarketingInbound({\n name,\n email,\n phone,\n address,\n coordinates,\n lastSelectedCrop,\n allViewedCrops,\n suitabilitySummary,\n });\n\n captureEvent('public-suitability-tool-submit-success');\n } catch (err) {\n captureEvent('public-suitability-tool-submit-error');\n console.error(err);\n }\n };\n\n const enterDrawMode = async () => {\n // Remove existing features\n const data = emptyFeature();\n await setSourceData(loadedMap, MAIN_SOURCE_ID, data);\n\n resetSelectedFeatures();\n\n setIsDrawMode(true);\n setStep(STEPS.SELECT_REGIONS);\n };\n\n if (step === STEPS.POST_SUBMIT) {\n // NOTE: this approach means that the post-submit step removes the map, so\n // the \"Back\" button in has to reload the page to get it back.\n // Not ideal but it works for now (better solution would be a full-page overlay).\n return ;\n }\n\n return (\n \n
\n \n {/* Show demo map background for the initial step: */}\n {step === STEPS.INPUT_ADDRESS && }\n\n {step === STEPS.INPUT_ADDRESS && (\n \n
\n \n
Explore crop suitability for your land
\n
\n Enter your address or coordinates\n
\n
\n {\n const map = mapRef.current;\n if (!map) return;\n\n captureEvent('public-suitability-tool-address-submit', {\n address,\n center,\n });\n\n dataToSubmitRef.current.address = address;\n dataToSubmitRef.current.coordinates = `${center.lng},${center.lat}`;\n\n map.setCenter(center);\n setStep(STEPS.LOADING_BOUNDARIES);\n }}\n conusOnly\n />\n
\n
\n )}\n\n {loadingMessage && (\n \n \n
{loadingMessage}
\n
\n \n
\n
\n
\n )}\n\n {step === STEPS.BOUNDARY_LOAD_FAILURE && (\n \n \n
\n Pre-loaded parcel boundaries are not available for your land\n
\n\n
\n {\n setIsDrawMode(true);\n setStep(STEPS.SELECT_REGIONS);\n }}\n >\n Draw parcels\n \n\n {\n await addFallbackBoundary(\n mapRef,\n toggleFeatureId,\n resetSelectedFeatures,\n );\n setStep(STEPS.SELECT_REGIONS);\n }}\n >\n Analyze region\n \n
\n
\n
\n )}\n\n {step === STEPS.DRAW_MODE_PROMPT && (\n \n \n
Draw parcels instead?
\n\n
\n
\n This will remove existing land parcels on the map\n
\n
\n \n Draw parcels\n \n\n {\n setStep(STEPS.SELECT_REGIONS);\n }}\n >\n Cancel\n \n
\n
\n
\n
\n )}\n\n {[STEPS.INPUT_ADDRESS, STEPS.LOADING_BOUNDARIES].includes(step) && (\n \n \n \n )}\n\n {step === STEPS.SELECT_REGIONS && (\n \n {\n // reset draw mode\n setIsDrawMode(false);\n\n // reset crop/tileset selection\n setSelectedTilesetId(null);\n\n // reset features\n loadedMap\n .getSource(MAIN_SOURCE_ID)\n .setData(featureCollection(emptyFeature()));\n\n // reset feature selection\n resetSelectedFeatures();\n\n // reset step\n setStep(STEPS.INPUT_ADDRESS);\n }}\n >\n \n \n\n {!isDrawMode && (\n {\n const features = getNonFallbackFeatures(loadedMap);\n if (features.length > 0) {\n setStep(STEPS.DRAW_MODE_PROMPT);\n } else {\n await enterDrawMode();\n }\n }}\n >\n Draw parcels\n \n )}\n \n )}\n\n {isDrawMode && (\n \n {drawModeFeatureIsSelected && (\n {\n await deleteSelectedDrawnFeature();\n\n updateSelectedFeatures();\n }}\n >\n Delete parcel\n \n )}\n\n \n Create parcel\n \n \n )}\n\n {step === STEPS.SELECT_REGIONS && (\n \n )}\n
\n\n {step !== STEPS.INPUT_ADDRESS && userHasSelectedAFeature && (\n {\n await submitInbound(data);\n setStep(STEPS.POST_SUBMIT);\n }}\n />\n )}\n\n {/* These components don't render anything: */}\n {mapLoaded && }\n {mapLoaded && (\n \n )}\n
\n );\n};\n\nexport default PublicSuitabilityTool;\n","import PublicSuitabilityTool from '../components/public-suitability-tool/PublicSuitabilityTool';\nimport ErrorBoundaryView, { NotFoundView } from '../views/ErrorBoundaryView';\n\nconst MarketingRoutes = {\n errorElement: ,\n path: 'marketing',\n children: [\n {\n path: 'public-suitability-tool',\n element: ,\n },\n {\n path: '*',\n element: ,\n },\n ],\n};\n\nexport default MarketingRoutes;\n","import { render } from 'react-dom';\nimport { createBrowserRouter, RouterProvider } from 'react-router-dom';\n\nimport MarketingRoutes from '../routes/MarketingRoutes';\nimport { initAnalytics } from '../utils/analytics';\nimport { initMonitoring } from '../utils/monitoring';\nimport { muteMapboxAbortErrors } from '../utils/muteMapboxAbortErrors';\n\ninitAnalytics();\ninitMonitoring();\n\nconst router = createBrowserRouter([MarketingRoutes]);\n\ndocument.addEventListener('DOMContentLoaded', () => {\n const rootNode = document.createElement('div');\n rootNode.className = 'root';\n\n render(\n ,\n document.body.appendChild(rootNode),\n );\n});\n\nif (process.env.NODE_ENV === 'development') {\n muteMapboxAbortErrors();\n}\n"],"names":["circle","center","radius","options","steps","properties","coordinates","i","destination","polygon","DROP_SHADOW","MainContainer","styled","BREAKPOINTS","FullOverlay","CardBase","LoadingCard","PromptCard","InfoCard","InfoText","ButtonWithXs","Button","ResponsiveButton","sizes","props","size","useBreakpointSize","jsx","DemoMapBackground","LinkNewTab","href","children","LAND_BOUNDARIES_PREFIX","MAIN_SOURCE_ID","CLU_PADDING_FACTOR","CLU_TIMEOUT","ZOOM_FOR_ADDRESS","ZOOM_FOR_FALLBACK","FALLBACK_FEATURE_ID","FALLBACK_FEATURE_RADIUS","INIT_MAP_POSITION","TILESET_SPEC","CHINESE_CHESTNUT_TILESET_NAME","BLACK_LOCUST_TILESET_NAME","HYBRID_POPLAR_TILESET_NAME","BLACKCURRANT_TILESET_NAME","AMERICAN_ELDERBERRY_TILESET_NAME","AMERICAN_HAZELNUT_TILESET_NAME","INIT_SELECTED_FEATURE_IDS_STATE","STEPS","PUBLIC_CLU_BASE_PATH","LOADING_MESSAGES","LOADING_MESSAGE_DURATION","SIDE_PANEL_WIDTHS","SUITABILITY_INPUTS","DRAWN_FEATURE_ID_PREFIX","CROP_INFOS","jsxs","Fragment","CancelError","reason","promiseState","_PCancelable","executor","__privateAdd","_PCancelable_instances","_cancelHandlers","_rejectOnCancel","_state","_promise","_reject","__privateSet","resolve","reject","onResolve","value","__privateGet","onCancel","__privateMethod","setState_fn","onReject","error","handler","boolean","userFunction","arguments_","onFulfilled","onRejected","onFinally","state","PCancelable","sortTilesetSuitability","tilesets","_","t","getSelectedFeatures","map","selectedFeatureIds","selectedFeatures","feature","loadCluToMapWithTimeout","mapRef","merge","source","existingFeatures","completed","cancelablePromise","cancelled","waitForSuccess","newFeatures","loadCluBoundaries","newData","turf.featureCollection","newFeatureIds","addFallbackBoundary","toggleFeatureId","resetSelectedFeatures","id","lng","lat","units","turf.circle","data","setSourceData","layerForTileset","tilesetId","_a","layerIdForTileset","getNonFallbackFeatures","f","SELECTED_FEATURES_SOURCE_ID","PREFIX","HOVERED_FEATURE_SOURCE_ID","MAIN_LAYER_ID","SELECTED_FEATURES_LAYER_ID","HOVERED_FEATURE_LAYER_ID","INTERACTION_LAYER_ID","MAIN_COLOR","HOVERED_COLOR","SELECTED_COLOR","SOURCE_SETTINGS","LandBoundariesLayer","isDrawMode","hoveredFeatureId","setHoveredFeatureId","useState","selectedFeatureIdsRef","useLatest","isDrawModeRef","useEffect","emptyGeojson","onMouseMove","e","onMouseLeave","onClick","emptyFeature","hoveredFeatures","featureCollection","visibility","Panel","SloganText","SubsloganText","Highlighted","InputField","type","autoComplete","placeholder","required","Field","Input","OnlyMobile","OnlyDesktop","Slogan","InboundForm","onSubmit","Formik","Form","CTAPanel","modalIsOpen","setModalIsOpen","isLargerScreen","useWindowSize","BREAKPOINT_VALUES","Modal","o","ModalBody","loadTilesetsMetadata","response","responseText","json","results","suitabilityAcrossLayers","layerIds","layers","getClippableTilesetLayers","originalPosition","originalUniformValues","layer","bounds","turf.bbox","calculateSuitabilityFromMap","getCalculateSuitabilityFromMap","getSuitabilityForLayer","painter","customLayer","sourceCacheKey","MAPBOX_SOURCECACHE_LAYER_PREFIX","sourceCache","coords","suitabilityByLayerId","err","opacity","fadeFactor","useDisablePageZoom","tag","initValue","useTilesetsData","setTilesets","fetchedData","tilesetSpecWithData","spec","tilesetData","tileset","useUpdateTilesetVisibility","selectedTilesetId","shouldShowTileset","selectedLayer","TILESET_RASTER_OPACITY","useSelectedFeatures","userHasSelectedAFeature","setUserHasSelectedAFeature","featureSelectionMap","setFeatureSelectionMap","useToggleMap","useMemo","key","setSelectedFeatures","updateSelectedFeatures","useCallback","features","setSelectedFeatureIds","ids","useCluLoading","loadingMessageIndex","setLoadingMessageIndex","loadingMessage","cluLoadingInterval","useRef","setCluLoading","x","setCluNotLoading","useSuitabilityPerCrop","suitabilityPerCrop","setSuitabilityPerCrop","calculateSuitability","newSuitabilityPerCrop","name","displayName","suitableAcres","onSourceData","tile","sourceId","isSourceLoaded","TILESET_LAYER_PREFIX","useDrawMode","setLayerDataFn","setLayerDataRef","setIsDrawMode","isDrawing","setIsDrawing","mapboxDrawRef","selectedFeatureId","setSelectedFeatureId","featureIsSelected","NON_DRAWN_FEATURE_ID_PREFIX","drawPolygon","mapboxDraw","deleteFeature","setLayerData","mapboxDrawFeature","filteredFeatures","deleteAll","MapboxDraw","updateData","dataWithIds","onSelectionChange","onModeChange","mode","DEFAULT_BACKGROUND","HOVER_BACKGROUND","SELECTED_BACKGROUND","SELECTED_CLASS","makeGreenButton","Component","ResponsiveGreenButtonComponent","GreenButton","active","Container","CropInfo","currentCropName","description","Header","Body","CropSuitabilityContainer","CropInfoContainer","SuitabilityInfoContainer","CropInfoSection","CropSelectorContainer","Row","TABS","TabButton","tab","currentTab","setTab","methodologyTitle","text","Icon","SectionsIcon","CropIcon","SuitabilityIcon","captureEvent","CropSelector","sortedTilesetsWithSuitability","selectTileset","showSuitableAcres","acresToShow","unitForValue","SuitableAcresTab","CropInfoTab","selectedTilesetName","SuitabilityInput","SuitabilityInfoTab","inputName","InfoPanel","reset","isMobile","useIsMobile","tilesetsWithSuitability","selectedFeaturesCount","selectedFeaturesArea","turf.area","acresPerSqMeter","selectedFeatureIsFallback","windowWidth","style","PositionedOverMap","PostSubmitMessage","PostSubmit","submitMarketingInbound","email","phone","address","lastSelectedCrop","allViewedCrops","suitabilitySummary","useAsSequentialAsync","fn","fnRef","asSequentialAsync","PublicSuitabilityTool","mapContainer","mapLoaded","setMapLoaded","loadedMap","useInitializeMapEffect","addReferenceLayers","step","setStep","useEffectOnce","forceMapResize","useAddClippableTilesetLayers","setSelectedTilesetId","transformData","existing","getSourceData","drawModeFeatureIsSelected","deleteSelectedDrawnFeature","deleteAllDrawnFeatures","infoPanelResetHandler","crops","max","mostSuitableCrop","acresForCrop","dataToSubmitRef","cropsWithSuitability","crop","submitInbound","allViewedCropsSet","enterDrawMode","MapContainer","AddressSearch","Spinner","Logo","ChevronIcon","NaipLayer","MarketingRoutes","ErrorBoundaryView","NotFoundView","initAnalytics","initMonitoring","router","createBrowserRouter","rootNode","render","RouterProvider"],"mappings":"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","x_google_ignoreList":[0,3]}