1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3839],{5751:(e,t,s)=>{"use strict";s.r(t),s.d(t,{__N_SSP:()=>C,default:()=>q});var a=s(37876),n=s(82904),r=s(18847),o=s.n(r),i=s(89099),l=s(14232),d=s(49915),h=s(85392),m=s(74),c=s(5876),u=s(94292),x=s(93408),g=s(56785),p=s(49086),f=s(66837),w=s(99098);let j=({routeShape:e,routeStops:t,vehicleClass:s})=>{let n=(0,w.qo)(e);return(0,a.jsx)("div",{className:"mb-4",children:(0,a.jsxs)("dl",{className:"grid grid-cols-2 gap-5 sm:grid-cols-3",children:[(0,a.jsxs)("div",{className:"overflow-hidden rounded-lg bg-white px-4 py-5 shadow shadow-lg sm:p-6",children:[(0,a.jsx)("dt",{className:"truncate text-sm font-medium text-gray-500",children:"Stations"}),(0,a.jsxs)("dd",{className:"mt-1 text-3xl font-semibold tracking-tight text-gray-900",children:[t?.length||0,(0,a.jsx)("div",{className:"text-sm text-gray-500 font-normal",children:"Stations on this route"})]})]}),(0,a.jsxs)("div",{className:"overflow-hidden rounded-lg bg-white px-4 py-5 shadow shadow-lg sm:p-6",children:[(0,a.jsx)("dt",{className:"truncate text-sm font-medium text-gray-500",children:"Total Distance"}),(0,a.jsxs)("dd",{className:"mt-1 text-3xl font-semibold tracking-tight text-gray-900",children:[n," km",(0,a.jsx)("div",{className:"text-sm text-gray-500 font-normal",children:"Route length"})]})]}),(0,a.jsxs)("div",{className:"overflow-hidden rounded-lg bg-white px-4 py-5 shadow shadow-lg sm:p-6 relative",children:[(0,a.jsx)("dt",{className:"truncate text-sm font-medium text-gray-500",children:"Vehicle Type"}),(0,a.jsxs)("dd",{className:"mt-1 text-3xl font-semibold tracking-tight text-gray-900",children:[(0,a.jsx)("span",{children:s?.name||"Unknown"}),(0,a.jsx)("div",{className:"absolute right-4 top-1/2 -translate-y-1/2",children:(0,a.jsx)("div",{className:"w-14 h-14 rounded-full border-2 border-black flex items-center justify-center",children:(0,a.jsx)(f.A,{iconSlug:s?.icon,size:48,color:"#fff",textColor:"#000"})})})]})]})]})})};var N=s(89214),y=s(88627),b=s(49825);let v=[{question:"What type of route is this?",answer:({network:e,vehicleClass:t})=>`This is a ${t?.name||"transit"} route operated by ${e?.name||"Unknown"}.`},{question:"What areas does this route serve?",answer:({route:e})=>`This route runs from ${e?.route_origin||"Unknown"} to ${e?.route_destination||"Unknown"}. ${e?.route_desc?`It ${e.route_desc.toLowerCase()}`:""}`},{question:"Network Information",answer:({route:e,network:t})=>{let s=`This route is part of the ${t?.name||"Unknown"} network. `;return e?.route_short_name&&(s+=`It is identified as Route ${e.route_short_name}`,e?.route_long_name&&(s+=` (${e.route_long_name})`),s+="."),s}},{question:"Why are some stops not on the route?",answer:()=>"Routes are created by combining information from multiple scheduled trips. A trip is a single journey from start to finish, while a route represents the overall service pattern. The route shape you see on the map comes from these individual trips. Sometimes, stops may appear to be off the route because they're used in some trips but not others, or they might be used only at certain times of day. This helps transit agencies provide flexible service while maintaining the same route number and name."},{question:"Why is there more than one of the same stop?",answer:()=>"Similar to why some stops may appear off-route, double or duplicate stops in the route view are also related to how GTFS data combines different trips into a single route. When you see multiple stops in the same location, it usually means that different trips on this route might use slightly different stop positions - for example, different platforms at the same station, or stops on opposite sides of the street. While these stops serve essentially the same location, they're technically distinct in the transit system's data to help with precise trip planning and real-time tracking."}],_=({route:e,network:t,vehicleClass:s})=>(0,a.jsx)("div",{children:(0,a.jsx)("dl",{className:"space-y-6 divide-y divide-gray-900/10",children:v.map(n=>(0,a.jsxs)(N.EN,{as:"div",className:"pt-6",children:[(0,a.jsx)("dt",{children:(0,a.jsxs)(N._q,{className:"group flex w-full items-start justify-between text-left text-gray-900",children:[(0,a.jsx)("span",{className:"text-base font-semibold leading-7",children:n.question}),(0,a.jsxs)("span",{className:"ml-6 flex h-7 items-center",children:[(0,a.jsx)(y.A,{"aria-hidden":"true",className:"h-6 w-6 group-data-[open]:hidden"}),(0,a.jsx)(b.A,{"aria-hidden":"true",className:"h-6 w-6 [.group:not([data-open])_&]:hidden"})]})]})}),(0,a.jsx)(N.kS,{as:"dd",className:"mt-2 pr-12",children:(0,a.jsx)("p",{className:"text-base leading-7 text-gray-600",children:n.answer({route:e,network:t,vehicleClass:s})})})]},n.question))})}),k=({routeShape:e,routeTerminals:t,network:s})=>{let n=(0,l.useRef)(null),r=(0,w.gO)(e),o=(0,w.qo)(r),i=0;return t?.length>=2&&(i=(0,w.HJ)(t[0],t[t.length-1])),(0,l.useEffect)(()=>{let e=(r||[]).flat();if(!n.current||!e.length)return;let a=n.current;a.width=a.offsetWidth,a.height=a.offsetHeight;let o=a.getContext("2d"),i=e.map(e=>parseFloat(e.lat)),l=e.map(e=>parseFloat(e.lon)),d=Math.min(...i),h=Math.max(...i),m=Math.min(...l),c=Math.max(...l),u=(h+d)/2,x=(c+m)/2,g=+Math.min((a.width-80)/(c-m),(a.height-80)/(
1h-d)),p=a.width/2,f=a.height/2;o.clearRect(0,0,a.width,a.height),o.strokeStyle=s?.color||"#222",o.lineWidth=2,(r||[]).forEach(e=>{o.beginPath(),e.forEach((e,t)=>{let s=p+(parseFloat(e.lon)-x)*g,a=f-(parseFloat(e.lat)-u)*g;0===t?o.moveTo(s,a):o.lineTo(s,a)}),o.stroke()});let w=r?.[0];if(t?.length>=2&&w?.length>=2){o.beginPath(),o.strokeStyle=s?.darkerColor||"#000",o.lineWidth=2,o.setLineDash([5,5]);let e=p+(parseFloat(w[0].lon)-x)*g,t=f-(parseFloat(w[0].lat)-u)*g,a=p+(parseFloat(w[w.length-1].lon)-x)*g,n=f-(parseFloat(w[w.length-1].lat)-u)*g;o.moveTo(e,t),o.lineTo(a,n),o.stroke(),o.setLineDash([]),o.font="10px Arial",o.fillStyle="#000",o.textAlign="center",o.textBaseline="bottom",o.fillText("Origin",e,t-10),o.fillText("Destination",a,n-10)}},[r,s,t]),(0,a.jsx)("div",{className:"mb-8",children:(0,a.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-8",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h2",{className:"text-2xl font-bold mb-4 text-gray-900",children:"Route Distance"}),(0,a.jsxs)("p",{className:"text-gray-600",children:["This route is ",(0,a.jsxs)("span",{className:"font-semibold",children:[o," kilometers"]})," long following the actual track. The direct distance between the first (",t[0]?.name,") and last station (",t[t.length-1]?.name,") as the crow flies is ",(0,a.jsxs)("span",{className:"font-semibold",children:[i," kilometers"]}),".",i>0&&o>0&&(0,a.jsxs)("span",{children:[" This means the route is ",Math.round((o/i-1)*100),"% longer than a direct path."]})]})]}),(0,a.jsx)("div",{className:"w-full h-64 bg-white rounded-lg",children:(0,a.jsx)("canvas",{ref:n,width:400,height:256,style:{width:"100%",height:"100%",objectFit:"contain"},className:"w-full h-full"})})]})})};var $=s(69973),S=s(95389),M=s(74880),T=s(73865),F=s(78240);let A=o()(()=>Promise.all([s.e(1808),s.e(9863),s.e(3368),s.e(7707),s.e(8647)]).then(s.bind(s,8647)),{loadableGenerated:{webpack:()=>[8647]},ssr:!1});var C=!0;function q({network:e}){let t=(0,i.useRouter)(),[s,r]=(0,l.useState)(null),{networkSlug:o,routeId:f}=t.query,{t:w}=(0,T.B)(),N=(0,g.A)({networkName:e?.name,networkSlug:o,network:e}),{routeDetails:y,isLoading:b,isError:v}=(0,F.kO)(e?.slug,f),{routes:C,isLoading:R}=(0,F.L6)(e?.slug,f),I=C?.shapes,D=C?.stops,E=C?.route||y,L=M.Y.getNetwork(o),U=L?L.cities:[],W=U.length>0?U.join(", "):"various cities",P=(0,l.useMemo)(()=>[{name:w("networks"),href:"/networks",current:!1},{name:e?.name||o,href:`/networks/${o}/`,current:!1},{name:E?.route_long_name||f,href:`/networks/${o}/routes/${f}/`,current:!0}],[e?.name,o,f,E?.route_long_name,w]);(0,l.useEffect)(()=>{window.gtag&&window.gtag("event","page_view",{page_title:`${e.name} Route Details | trains.fyi`,page_location:window.location.href,page_path:`/networks/${o}/routes/${f}/`})},[e.name,o,f]);let O=E?`${E.route_short_name} - ${E.route_long_name} | ${e?.name||"Transit"} Route`:`Route Details | ${e?.name||"Transit"} Network`,H=E?`View details, stops, and map for ${E.route_long_name} (${E.route_short_name}) on the ${e?.name||"transit"} network in ${W}.`:`Explore route information for the ${e?.name||"transit"} network in ${W}.`,B=`/networks/${o}/routes/${f}/`,V=E?`${E.route_short_name}, ${E.route_long_name}, ${e?.name||"transit"} route, public transit, train route, transit map, ${W}`:`transit routes, ${e?.name||"transit"} network, public transportation, ${W}`,G=E&&e?`/api/og?mode=route&network=${encodeURIComponent(e.name)}&route=${encodeURIComponent(E.route_long_name||E.route_short_name||f)}&bg=${encodeURIComponent(e.color||"1e3a8a")}&tc=${encodeURIComponent(e.textColor||"ffffff")}`:"/social.png";if(v)return(0,a.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,a.jsx)(x.A,{title:`Route Not Found | ${e?.name||"Transit"} Network`,description:"The requested route information is currently unavailable.",canonical:B}),(0,a.jsx)(m.A,{networkNav:N}),(0,a.jsx)("main",{className:"flex-grow",children:(0,a.jsx)("div",{className:"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-8",children:(0,a.jsx)("div",{className:"rounded-md bg-yellow-50 p-4",children:(0,a.jsxs)("div",{className:"flex",children:[(0,a.jsx)("div",{className:"flex-shrink-0",children:(0,a.jsx)(n.A,{className:"h-5 w-5 text-yellow-400","aria-hidden":"true"})}),(0,a.jsxs)("div",{className:"ml-3",children:[(0,a.jsx)("h3",{className:"text-sm font-medium text-yellow-800",children:w("routeDataUnavailableTitle")}),(0,a.jsx)("div",{className:"mt-2 text-sm text-yellow-700",children:(0,a.jsx)("p",{children:w("routeDataUnavailableBody")})})]})]})})})}),(0,a.jsx)(h.A,{})]});if(b||R||!e)return(0,a.jsxs)("div",{className:"flex items-center justify-center h-screen",children:[(0,a.jsx)(x.A,{title:`Loading Route Details | ${e?.name||"Transit"} Network`,description:"Loading route information...",canonical:B}),(0,a.jsx)(c.A,{text:w("routeLoadingText")})]});let J=e?.color||"#000000",X=e?.textColor||"#FFFFFF",z=E?.route_color?`#${E.route_color}`:J,Y=S.L[E?.route_type];return(0,a.jsxs)("div",{className:"flex flex-col min-h-screen",children:[(0,a.jsx)(x.A,{title:O,description:H,canonical:B,image:G,keywords:V}),(0,a.jsx)(m.A,{networkNav:N}),(0,a.jsx)("main",{className:"flex-grow",children:(0,a.jsxs)("div",{className:"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8",children:[(0,a.jsx)("div",{className:"py-4",children:(0,a.jsx)(d.A,{pages:P})}),(0,a.jsxs)("div",{className:"my-8 grid grid-cols-1 md:grid-cols-3 gap-8",children:[(0,a.jsxs)("div",{className:"md:col-span-2",children:[(0,a.jsx)("div",{className:"text-5xl font-bold text-gray-900 mb-4",children:E?.route_short_name}),(0,a.jsx)("h1",{className:"text-3xl text-gray-900 text-gray-600 mb-2",children:E?.route_long_name}),(0,a.jsx)("div",{className:"text-xl text-gray-500",children:w("routeLabel").replace("{name}",e?.name)})]}),(0,a.jsx)("div",{className:"flex items-start justify-end",children:(0,a.jsx)("a",{href:`/networks/${o}/`,className:"inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500",children:w("routeViewAllRoutes")})})]}),(0,a.jsx)(j,{routeDetails:E,routeStops:D,vehicleClass:Y,routeShape:I,network:e}),(0,a.jsx)(p.A,{networkSlug:o,routeIds:f?[f]:[],stopIds:D?.map(e=>e.stop_id)||[]}),(0,a.jsx)("div",{className:"mb-8 mt-16",children:(0,a.jsx)(A,{networkSlug:o,routeId:f,routeShape:I,routeStops:D,routeC
1olor:z,textColor:X,selectedStop:s,height:600})}),(0,a.jsxs)("div",{className:"mb-20 mt-8",children:[(0,a.jsx)("h2",{className:"text-2xl font-bold leading-7 text-gray-900",children:w("routeStopsH2").replace("{route}",E?.route_long_name||"this route")}),(0,a.jsx)("p",{className:"text-base mt-2 text-gray-500",children:w("routeStopsSubtitle")}),(0,a.jsx)("div",{className:"mt-6",children:(0,a.jsx)(u.A,{items:D||[],renderItem:e=>(0,a.jsx)($.A,{stopName:e.name||e.stop_name,onClick:()=>r(e),highlightColor:z,isSelected:s?.stop_id===e.stop_id,containerClassName:"rounded-lg py-1 pr-2 transition-all duration-200 hover:bg-gray-50"}),connectingLineColor:"bg-gray-200"})})]}),(0,a.jsx)("h2",{className:"text-2xl font-bold tracking-tight text-gray-900 mt-24 mb-4",children:w("routeDetailsH2")}),(0,a.jsx)("div",{className:"mb-8",children:(0,a.jsx)(_,{route:E,network:e,vehicleClass:Y})}),(0,a.jsx)("div",{className:"my-20",children:(0,a.jsx)(k,{network:e,routeShape:I,routeTerminals:D?.length>=2?[D[0],D[D.length-1]]:[]})})]})}),(0,a.jsx)(h.A,{})]})}},11114:(e,t,s)=>{(window.__NEXT_P=window.__NEXT_P||[]).push(["/networks/[networkSlug]/routes/[routeId]",function(){return s(5751)}])},99098:(e,t,s)=>{"use strict";s.d(t,{HJ:()=>r,gO:()=>a,qo:()=>n});let a=e=>e&&e.length?Array.isArray(e[0])||void 0===e[0].lat?e:[e]:[],n=e=>{let t=a(e);if(!t.length)return 0;let s=e=>e*Math.PI/180,n=(e,t)=>{let a=s(parseFloat(e.lat.toString())),n=s(parseFloat(e.lon.toString())),r=s(parseFloat(t.lat.toString())),o=s(parseFloat(t.lon.toString())),i=r-a,l=o-n,d=Math.sin(i/2)*Math.sin(i/2)+Math.cos(a)*Math.cos(r)*Math.sin(l/2)*Math.sin(l/2);return 2*Math.atan2(Math.sqrt(d),Math.sqrt(1-d))*6371},r=0;for(let e of t){let t=0;for(let s=0;s<e.length-1;s++)t+=n(e[s],e[s+1]);t>r&&(r=t)}return Math.round(r)},r=(e,t)=>{if(!e?.lat||!e?.lon||!t?.lat||!t?.lon)return 0;let s=e=>e*Math.PI/180,a=s(parseFloat(e.lat.toString())),n=s(parseFloat(e.lon.toString())),r=s(parseFloat(t.lat.toString())),o=s(parseFloat(t.lon.toString())),i=r-a,l=o-n,d=Math.sin(i/2)*Math.sin(i/2)+Math.cos(a)*Math.cos(r)*Math.sin(l/2)*Math.sin(l/2);return Math.round(2*Math.atan2(Math.sqrt(d),Math.sqrt(1-d))*6371)}}},e=>{e.O(0,[6701,3927,2325,1002,3990,8447,5392,4503,9074,636,6593,8792],()=>e(e.s=11114)),_N_E=e.O()}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.