import{cD as ge,d8 as Be,b6 as W,aX as V,dr as We,dO as qe,dP as e,bT as O,B as Q,ed as y,Z as P,ab as X,ai as _,eA as E,cF as S,bS as ne,aB as se,bd as Ye,b0 as Ue,y as be,D as _e,ar as Qe,a_ as ve,eT as Ne,au as Ge,av as Ke,ah as Xe,a0 as q,X as Z,r as T,a4 as H,ea as ue,ae as Je,fn as ie,eF as we,aO as je,co as De,f8 as Se,f7 as ye,eH as G,fp as te,ct as ee,eN as Ze,ao as Y,v as oe,a6 as ae,a3 as et,eK as z,dK as Ie,be as ke,aS as tt,eu as st,A as nt,cT as at,aD as Ce,dL as rt,em as it,eS as ot,fc as lt,e_ as ct,fq as dt,es as ut,cA as he,aF as Pe,_ as ht,bo as mt,eM as ft,eR as pt,dn as xt,am as gt,bO as bt,c2 as vt,ee as Nt,cH as wt,cd as Re,al as jt}from"./index-BJCd-jqX.js";import{u as K}from"./tcd-CzSyL1Q2.js";import{D as Dt,C as St,P as yt}from"./dnd.esm-DY-Luov9.js";const It=[["path",{d:"M22 12A10 10 0 1 1 12 2",key:"1fm58d"}],["path",{d:"M22 2 12 12",key:"yg2myt"}],["path",{d:"M16 2h6v6",key:"zan5cs"}]],kt=ge("circle-arrow-out-up-right",It);const Ct=[["path",{d:"m18 14 4 4-4 4",key:"10pe0f"}],["path",{d:"m18 2 4 4-4 4",key:"pucp1d"}],["path",{d:"M2 18h1.973a4 4 0 0 0 3.3-1.7l5.454-8.6a4 4 0 0 1 3.3-1.7H22",key:"1ailkh"}],["path",{d:"M2 6h1.972a4 4 0 0 1 3.6 2.2",key:"km57vx"}],["path",{d:"M22 18h-6.041a4 4 0 0 1-3.3-1.8l-.359-.45",key:"os18l9"}]],Pt=ge("shuffle",Ct);var J={exports:{}},Rt=J.exports,me;function Tt(){return me||(me=1,(function(s){(function(a){const i="(0?\\d+|0x[a-f0-9]+)",c={fourOctet:new RegExp(`^${i}\\.${i}\\.${i}\\.${i}$`,"i"),threeOctet:new RegExp(`^${i}\\.${i}\\.${i}$`,"i"),twoOctet:new RegExp(`^${i}\\.${i}$`,"i"),longValue:new RegExp(`^${i}$`,"i")},u=new RegExp("^0[0-7]+$","i"),f=new RegExp("^0x[a-f0-9]+$","i"),m="%[0-9a-z]{1,}",x="(?:[0-9a-f]+::?)+",N={zoneIndex:new RegExp(m,"i"),native:new RegExp(`^(::)?(${x})?([0-9a-f]+)?(::)?(${m})?$`,"i"),deprecatedTransitional:new RegExp(`^(?:::)(${i}\\.${i}\\.${i}\\.${i}(${m})?)$`,"i"),transitional:new RegExp(`^((?:${x})|(?:::)(?:${x})?)${i}\\.${i}\\.${i}\\.${i}(${m})?$`,"i")};function j(t,n){if(t.indexOf("::")!==t.lastIndexOf("::"))return null;let l=0,r=-1,o=(t.match(N.zoneIndex)||[])[0],d,v;for(o&&(o=o.substring(1),t=t.replace(/%.+$/,""));(r=t.indexOf(":",r+1))>=0;)l++;if(t.substr(0,2)==="::"&&l--,t.substr(-2,2)==="::"&&l--,l>n)return null;for(v=n-l,d=":";v--;)d+="0:";return t=t.replace("::",d),t[0]===":"&&(t=t.slice(1)),t[t.length-1]===":"&&(t=t.slice(0,-1)),n=(function(){const I=t.split(":"),g=[];for(let D=0;D0;){if(d=l-r,d<0&&(d=0),t[o]>>d!==n[o]>>d)return!1;r-=l,o+=1}return!0}function b(t){if(f.test(t))return parseInt(t,16);if(t[0]==="0"&&!isNaN(parseInt(t[1],10))){if(u.test(t))return parseInt(t,8);throw new Error(`ipaddr: cannot parse ${t} as octal`)}return parseInt(t,10)}function w(t,n){for(;t.length=0;o-=1)if(d=this.octets[o],d in r){if(v=r[d],l&&v!==0)return null;v!==8&&(l=!0),n+=v}else return null;return 32-n},t.prototype.range=function(){return h.subnetMatch(this,this.SpecialRanges)},t.prototype.toByteArray=function(){return this.octets.slice(0)},t.prototype.toIPv4MappedAddress=function(){return h.IPv6.parse(`::ffff:${this.toString()}`)},t.prototype.toNormalizedString=function(){return this.toString()},t.prototype.toString=function(){return this.octets.join(".")},t})(),h.IPv4.broadcastAddressFromCIDR=function(t){try{const n=this.parseCIDR(t),l=n[0].toByteArray(),r=this.subnetMaskFromPrefixLength(n[1]).toByteArray(),o=[];let d=0;for(;d<4;)o.push(parseInt(l[d],10)|parseInt(r[d],10)^255),d++;return new this(o)}catch{throw new Error("ipaddr: the address does not have IPv4 CIDR format")}},h.IPv4.isIPv4=function(t){return this.parser(t)!==null},h.IPv4.isValid=function(t){try{return new this(this.parser(t)),!0}catch{return!1}},h.IPv4.isValidCIDR=function(t){try{return this.parseCIDR(t),!0}catch{return!1}},h.IPv4.isValidFourPartDecimal=function(t){return!!(h.IPv4.isValid(t)&&t.match(/^(0|[1-9]\d*)(\.(0|[1-9]\d*)){3}$/))},h.IPv4.networkAddressFromCIDR=function(t){let n,l,r,o,d;try{for(n=this.parseCIDR(t),r=n[0].toByteArray(),d=this.subnetMaskFromPrefixLength(n[1]).toByteArray(),o=[],l=0;l<4;)o.push(parseInt(r[l],10)&parseInt(d[l],10)),l++;return new this(o)}catch{throw new Error("ipaddr: the address does not have IPv4 CIDR format")}},h.IPv4.parse=function(t){const n=this.parser(t);if(n===null)throw new Error("ipaddr: string is not formatted like an IPv4 Address");return new this(n)},h.IPv4.parseCIDR=function(t){let n;if(n=t.match(/^(.+)\/(\d+)$/)){const l=parseInt(n[2]);if(l>=0&&l<=32){const r=[this.parse(n[1]),l];return Object.defineProperty(r,"toString",{value:function(){return this.join("/")}}),r}}throw new Error("ipaddr: string is not formatted like an IPv4 CIDR range")},h.IPv4.parser=function(t){let n,l,r;if(n=t.match(c.fourOctet))return(function(){const o=n.slice(1,6),d=[];for(let v=0;v4294967295||r<0)throw new Error("ipaddr: address outside defined range");return(function(){const o=[];let d;for(d=0;d<=24;d+=8)o.push(r>>d&255);return o})().reverse()}else return(n=t.match(c.twoOctet))?(function(){const o=n.slice(1,4),d=[];if(r=b(o[1]),r>16777215||r<0)throw new Error("ipaddr: address outside defined range");return d.push(b(o[0])),d.push(r>>16&255),d.push(r>>8&255),d.push(r&255),d})():(n=t.match(c.threeOctet))?(function(){const o=n.slice(1,5),d=[];if(r=b(o[2]),r>65535||r<0)throw new Error("ipaddr: address outside defined range");return d.push(b(o[0])),d.push(b(o[1])),d.push(r>>8&255),d.push(r&255),d})():null},h.IPv4.subnetMaskFromPrefixLength=function(t){if(t=parseInt(t),t<0||t>32)throw new Error("ipaddr: invalid IPv4 prefix length");const n=[0,0,0,0];let l=0;const r=Math.floor(t/8);for(;l=0;v-=1)if(o=this.parts[v],o in r){if(d=r[o],l&&d!==0)return null;d!==16&&(l=!0),n+=d}else return null;return 128-n},t.prototype.range=function(){return h.subnetMatch(this,this.SpecialRanges)},t.prototype.toByteArray=function(){let n;const l=[],r=this.parts;for(let o=0;o>8),l.push(n&255);return l},t.prototype.toFixedLengthString=function(){const n=(function(){const r=[];for(let o=0;o>8,l&255,r>>8,r&255])},t.prototype.toNormalizedString=function(){const n=(function(){const r=[];for(let o=0;oo&&(r=d.index,o=d[0].length);return o<0?l:`${l.substring(0,r)}::${l.substring(r+o)}`},t.prototype.toString=function(){return this.toRFC5952String()},t})(),h.IPv6.broadcastAddressFromCIDR=function(t){try{const n=this.parseCIDR(t),l=n[0].toByteArray(),r=this.subnetMaskFromPrefixLength(n[1]).toByteArray(),o=[];let d=0;for(;d<16;)o.push(parseInt(l[d],10)|parseInt(r[d],10)^255),d++;return new this(o)}catch(n){throw new Error(`ipaddr: the address does not have IPv6 CIDR format (${n})`)}},h.IPv6.isIPv6=function(t){return this.parser(t)!==null},h.IPv6.isValid=function(t){if(typeof t=="string"&&t.indexOf(":")===-1)return!1;try{const n=this.parser(t);return new this(n.parts,n.zoneId),!0}catch{return!1}},h.IPv6.isValidCIDR=function(t){if(typeof t=="string"&&t.indexOf(":")===-1)return!1;try{return this.parseCIDR(t),!0}catch{return!1}},h.IPv6.networkAddressFromCIDR=function(t){let n,l,r,o,d;try{for(n=this.parseCIDR(t),r=n[0].toByteArray(),d=this.subnetMaskFromPrefixLength(n[1]).toByteArray(),o=[],l=0;l<16;)o.push(parseInt(r[l],10)&parseInt(d[l],10)),l++;return new this(o)}catch(v){throw new Error(`ipaddr: the address does not have IPv6 CIDR format (${v})`)}},h.IPv6.parse=function(t){const n=this.parser(t);if(n.parts===null)throw new Error("ipaddr: string is not formatted like an IPv6 Address");return new this(n.parts,n.zoneId)},h.IPv6.parseCIDR=function(t){let n,l,r;if((l=t.match(/^(.+)\/(\d+)$/))&&(n=parseInt(l[2]),n>=0&&n<=128))return r=[this.parse(l[1]),n],Object.defineProperty(r,"toString",{value:function(){return this.join("/")}}),r;throw new Error("ipaddr: string is not formatted like an IPv6 CIDR range")},h.IPv6.parser=function(t){let n,l,r,o,d,v;if(r=t.match(N.deprecatedTransitional))return this.parser(`::ffff:${r[1]}`);if(N.native.test(t))return j(t,8);if((r=t.match(N.transitional))&&(v=r[6]||"",n=r[1],r[1].endsWith("::")||(n=n.slice(0,-1)),n=j(n+v,6),n.parts)){for(d=[parseInt(r[2]),parseInt(r[3]),parseInt(r[4]),parseInt(r[5])],l=0;l128)throw new Error("ipaddr: invalid IPv6 prefix length");const n=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];let l=0;const r=Math.floor(t/8);for(;l{const a=[],i=[];return{resolvers:s.reduce((u,f)=>{const m=W[f.address];return m?a.includes(m)?i.push(f.address):(a.push(m),u.push(f)):u.push(f),u},[]),providers:a}},Ft=s=>function(a,i){let c;if(!(i&&a.searchDomain===i.searchDomain&&a.resolver===i.resolver)){if(a.searchDomain?c=s.routes[a.searchDomain]||[]:a.fallback?c=s.fallbackResolvers||[]:c=s.resolvers||[],c.some(u=>u.address===a.resolver))return`An entry for ${a.resolver} already exists.`;if(W[a.resolver]){const u=W[a.resolver];if(c.some(f=>V[u].includes(f.address)))return`${a.resolver} is part of ${u} Public DNS, which is already present.`}}},Ot=[$.parseCIDR("2a07:a8c0::/33"),$.parseCIDR("2a07:a8c1::/33")],Mt=[$.parseCIDR("2606:1a40::/48"),$.parseCIDR("2606:1a40:1::/48")],Lt=s=>{try{const a=$.parse(s);if(a.kind()==="ipv6"&&Ot.some(i=>a.match(i)))return a.toNormalizedString().split(":").slice(-4).join("").replace(/^0+/,"")}catch{}},At=s=>{try{const a=$.parse(s);if(a.kind()==="ipv6"&&Mt.some(i=>a.match(i))){const i=a.toNormalizedString().split(":").slice(-5,-1).map(c=>c.padStart(4,"0")).join("").replace(/^0+/,"");return zt(i)}}catch{}},$t=s=>{if((s.includes(":")||s.includes("."))&&$.isValid(s))return $.parse(s).toString();let a="";const i=".dns.nextdns.io",c="https://dns.nextdns.io/";if(s.endsWith(i)&&s.length>i.length?a=s.split(i)[0]:s.startsWith(c)&&s.length>c.length?a=s.split(c)[1]:qe(s)&&(a=s),a.length<=16&&a.length>=6){let u=[];const f=Math.ceil(a.length/4),m=a.length%4===0?4:a.length%4;for(let N=1;N<=f;N++){const j=Math.max(a.length-4*N,0),p=j===0?m:4;u.push(a.slice(j,j+p))}return u=u.reverse(),`2a07:a8c0::${u.join(":")}`}return""},Vt=s=>{if(s=s.replace(/=+$/,""),s.length<=13&&We(s)){const a=Ht(s.toLowerCase());let i=[];const c=Math.ceil(a.length/4),u=a.length%4===0?4:a.length%4;for(let m=1;m<=c;m++){const x=Math.max(a.length-4*m,0),N=x===0?u:4;i.push(a.slice(x,x+N))}return i=i.reverse(),`2606:1a40::${i.join(":")}:0`}return""};function Ht(s){return Number.parseInt(s,36).toString(16)}function zt(s){return Number.parseInt(s,16).toString(36)}function Ee(s){return e.jsx(O,{content:"Only clients that support split DNS (Tailscale v1.8 or later for most platforms) will use this nameserver. Older clients will ignore this nameserver.",children:e.jsxs(Q,{className:s.className,variant:"tag",color:"gray",children:[e.jsx(Pt,{className:"mr-1",size:"0.9em"}),"Split DNS"]})})}function fe(s){const[a,i]=y.useState(s),[c,u]=y.useState(void 0),f=y.useCallback(m=>{u(void 0),i(m)},[i,u]);return{value:a,error:c,setValue:f,setError:u}}function Fe(s){return e.jsx(O,{content:"Only clients with exit node DNS override support (Tailscale v1.88.1 for most platforms) will use this nameserver when the node is also configured to use an exit node. Older clients configured to use an exit node will use the exit node for DNS resolution.",children:e.jsxs(Q,{className:s.className,variant:"tag",color:"gray",children:[e.jsx(kt,{className:"mr-1",size:"0.9em"}),"Use with exit node"]})})}function Bt(s){const{disabled:a,initialValue:i,useFallbackResolvers:c,validateRoute:u,open:f,onSubmit:m,onOpenChange:x,triggeredFrom:N,hasDOHServer:j}=s,p=N==="nextdns",b=N==="controld",w=p||b,h=p?"NextDNS configuration":b?"Control D configuration":"nameserver",{value:t,error:n,setValue:l,setError:r}=fe(i?.resolver||""),{value:o,error:d,setValue:v,setError:I}=fe(i?.searchDomain||""),[g,D]=y.useState(i?.searchDomain!==void 0||j&&!w),[k,C]=y.useState(i?.useWithExitNode||!1),[M,F]=y.useState();y.useEffect(()=>{l(i?.resolver||""),v(i?.searchDomain||""),D(i?.searchDomain!==void 0||j&&!w),C(i?.useWithExitNode||!1)},[i,l,v,C,j,w]);function U(){let R,L;const A={resolver:t,searchDomain:g?o?.replace(/^\.|\.$/g,""):void 0,fallback:i?.fallback||c,useWithExitNode:k};if(p&&(A.resolver=$t(t)),b&&(A.resolver=Vt(t)),A.resolver===void 0||A.resolver===""?R=`Please provide a ${h}.`:se.isValid(A.resolver)?A.resolver==="0.0.0.0"&&(R="0.0.0.0 is not a valid resolver value."):R=p?"Invalid NextDNS endpoint. Please consult your NextDNS configuration page to get a valid endpoint. ":b?"Invalid Control D resolver ID. Please consult your Control D configuration page to get a valid endpoint.":se.errorMessage,g&&(o===void 0||o===""?L="Please provide a search domain to use.":Ye.isValid(o)||(L=se.errorMessage)),R||L){r(R),I(L);return}const de=u?.(A,i);if(de){r(de);return}t!==void 0&&(m(A,i,p,b),x(!1))}function Ae(R){const L=R.target.value.toLowerCase().replace(/^https?:\/\//i,"").replaceAll(/[^\d./:A-Fa-f]/g,"");l(L),F(void 0)}function $e(R){const L=R.target.value;v(L.replaceAll(/[^\w'./:~-]/g,"")),F(void 0)}function Ve(R){l(R.target.value)}const He=i?.resolver!==""&&i?.resolver!==void 0,ze=()=>i?.providerLabel?"You cannot edit the addresses of a public DNS provider preset.":p?"Enter your NextDNS endpoint. Your endpoint ID will be a hexadecimal string between 6-16 characters.":b?"Enter your Control D resolver ID. Your resolver ID will be a string made of characters and numbers.":"Use this IPv4 or IPv6 address to resolve names.",le="This nameserver will only be used for some domains.",ce="This nameserver will continue to be used when an exit node is selected.";return e.jsx(P,{open:f,onOpenChange:x,title:`${He?"Edit":"Add"} ${h}`,children:e.jsxs(P.Form,{disabled:a||t.length<6||g&&o.length===0,cancelButton:!0,submitButton:{children:"Save"},onSubmit:U,children:[e.jsx(X,{className:"my-8",label:w?"Endpoint":"Nameserver",description:ze(),error:n||M,children:e.jsx(_,{id:"nameserver",type:"text",disabled:a||!!i?.providerLabel,className:"mt-2",inputClassName:"tabular-nums",value:i?.providerLabel?`${i.providerLabel} Public DNS`:t,error:n!==void 0||M!==void 0,onChange:w?Ve:Ae,placeholder:p?"NextDNS endpoint, e.g. abc123":b?"Control D resolver ID, e.g. a0bcde1fgh":"1.2.3.4",autoCapitalize:"off",autoComplete:"off",autoFocus:!0})}),!w&&e.jsxs("div",{className:"@sm:flex justify-between items-center",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center",children:[e.jsx("label",{className:E.fieldLabel,htmlFor:"restrict",children:"Restrict to domain"}),e.jsx(Ee,{className:"relative ml-2"})]}),e.jsx("p",{className:S(E.fieldHelpText,"hidden @sm:block"),children:le})]}),e.jsx(O,{side:"top",content:j&&!w?"You have a DOH server configured as a global nameserver. Any additional nameservers must be restricted to a search domain.":null,children:e.jsx(ne,{className:"mt-2 @sm:mt-0 self-start shrink-0",sizeVariant:"large",id:"restrict",disabled:a||j&&!w,checked:g,onChange:R=>D(R)})}),e.jsx("p",{className:S(E.fieldHelpText,"@sm:hidden"),children:le})]}),g&&!w&&e.jsx(e.Fragment,{children:e.jsxs("div",{className:"mt-4",children:[e.jsx("label",{className:Wt,htmlFor:"searchdomain",children:"Domain"}),d!==void 0&&e.jsx("p",{className:S(E.fieldErrorText,"mt-1"),children:d}),e.jsx(_,{id:"searchdomain",type:"text",className:"mt-3",disabled:a,value:o,error:d!==void 0,placeholder:"example.com",autoCapitalize:"off",autoComplete:"off",onChange:$e}),e.jsx("p",{className:S(E.fieldHelpText,"mt-2"),children:"Only single-label or fully-qualified queries matching this suffix should use the nameserver."})]})}),e.jsxs("div",{className:"@sm:flex justify-between items-center mt-4",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center",children:[e.jsx("label",{className:E.fieldLabel,htmlFor:"usewithexitnode",children:"Use with exit node"}),e.jsx(Fe,{className:"relative ml-2"})]}),e.jsx("p",{className:S(E.fieldHelpText,"hidden @sm:block"),children:ce})]}),e.jsx(ne,{className:"mt-2 @sm:mt-0 self-start shrink-0",sizeVariant:"large",id:"usewithexitnode",disabled:a,checked:k,onChange:R=>C(R)}),e.jsx("p",{className:S(E.fieldHelpText,"@sm:hidden"),children:ce})]})]})})}const Wt=S(E.fieldLabel,"block mb-1"),re=Ue.forwardRef((s,a)=>{const{className:i,route:c,locked:u,disabled:f,readonly:m,onEdit:x,onEditNextDNS:N,onEditControlD:j,onDelete:p,deleteOnConfirm:b,...w}=s,[h,t]=y.useState(!1),n=v=>`${V[v][0]} and ${V[v].length-1} more`,l=v=>v.useWithExitNode?e.jsx(Fe,{className:"relative ml-2"}):"",r=Lt(c.resolver),o=At(c.resolver),d=y.useCallback(()=>{const v=c.providerLabel?V[c.providerLabel].map(I=>({...c,resolver:I})):[c];p?.(v)},[c,p]);return e.jsxs("div",{ref:a,className:S(i,"flex justify-between",{"hover:bg-bg-menu-item-hover":c.providerLabel}),...w,children:[e.jsx("div",{className:S("pl-4 flex flex-1 items-start",{"text-text-muted":f}),children:c.providerLabel?e.jsxs("button",{onClick:()=>t(!h),className:"block w-full tabular-nums pr-2 py-2",children:[e.jsxs("div",{children:[e.jsxs("span",{className:"inline-block",children:[c.providerLabel," Public DNS",l(c)]}),e.jsxs("span",{className:"inline-block text-text-muted float-right",children:[n(c.providerLabel),h?e.jsx(be,{className:"inline-block align-text-top ml-1",size:20}):e.jsx(_e,{className:"inline-block align-text-top ml-1",size:20})]})]}),e.jsx("ul",{className:S("text-text-muted mt-1 py-2 list-inside space-y-2",{hidden:!h}),children:V[c.providerLabel].map(v=>e.jsx("li",{className:"text-text-muted tabular-nums font-normal",children:v},v))})]}):e.jsx("div",{className:"tabular-nums pr-2 py-2 w-full",children:r?e.jsxs(e.Fragment,{children:["NextDNS:"," ",e.jsx("a",{href:`https://my.nextdns.io/${r}`,target:"_blank",title:"Modify NextDNS configuration",rel:"noopener noreferrer",className:"hover:underline",children:e.jsx("code",{className:"font-semibold",children:r})}),l(c)]}):o?e.jsxs(e.Fragment,{children:["Control D: ",o,l(c)]}):e.jsxs(e.Fragment,{children:[c.resolver,l(c)]})})}),u?e.jsx("div",{className:"p-2 pr-4 flex items-center justify-center",children:e.jsx(Qe,{className:"text-text-muted",style:{transform:"translateX(0.125rem) scale(0.75)"}})}):!m&&e.jsx("div",{className:"pr-2 pt-1.5",children:e.jsx(ve,{ariaLabel:`Actions for ${c.resolver}`,iconSize:"20",items:[{type:"item",label:"Edit…",hidden:!x,onSelect:()=>{r?N?.({...c,resolver:r}):o?j?.({...c,resolver:o}):x?.(c)}},{type:"separator",hidden:!x||!p},{type:"item",label:"Delete",intent:"danger",hidden:!p,onSelect:()=>d()},{type:"separator",hidden:!x||!p||!b},{type:"item",label:"Delete…",intent:"danger",hidden:!b,onSelect:()=>b?.()}]})})]})});function Oe(s){const{domain:a,resolvers:i,disabled:c,locked:u,fallback:f,readonly:m,onEdit:x,onEditNextDNS:N,onEditControlD:j,onDelete:p}=s,b=w=>({resolver:w.address,searchDomain:a,fallback:f,providerLabel:W[w.address],useWithExitNode:w.useWithExitNode});return e.jsx(e.Fragment,{children:i.map(w=>e.jsx(re,{className:"transition-shadow -mb-px",route:b(w),disabled:c,locked:u,readonly:m,onEdit:x,onEditNextDNS:N,onEditControlD:j,onDelete:p},w.address))})}function qt(s){const{config:a,useFallbackResolvers:i,onEdit:c,onDelete:u,onAddPreset:f,onTriggerNextDNS:m,onTriggerControlD:x,disabled:N,dispatch:j,readonly:p}=s,{data:b}=Ne(),w=i?a.fallbackResolvers:a.resolvers,h=Te(w),t=ue.every(o=>h.providers.includes(o)),n=h.resolvers.length===0,l="border bg-bg-base rounded-md divide-y overflow-hidden",r=Object.keys(a.routes);return e.jsxs(e.Fragment,{children:[e.jsxs("div",{children:[a.magicDNS&&a.magicDNSDomains.map((o,d)=>e.jsxs("div",{className:"mt-5",children:[e.jsxs("header",{className:"flex mb-1",children:[e.jsx("h4",{className:"font-medium mr-2 mb-1",children:o}),e.jsx("div",{className:"space-x-2 mb-1",children:e.jsx(O,{content:"This nameserver is used for MagicDNS. Disable MagicDNS to remove it.",children:e.jsxs(Q,{className:"text-sm relative -top-px",variant:"tag",color:"gray",children:[e.jsx(Ge,{className:"mr-1",size:"0.9em"}),e.jsx("span",{children:"MagicDNS"})]})})})]}),e.jsx("div",{className:l,children:e.jsx(re,{route:{resolver:Ke},locked:!0,readonly:p})})]},d)),e.jsx("div",{children:r.map(o=>a.routes[o]&&e.jsx(Yt,{routeCardClasses:l,domain:o,readonly:p,config:a,onEdit:c,onDelete:u},o))}),e.jsxs("div",{className:"mt-5",children:[e.jsxs("header",{className:"flex items-center mb-2",children:[e.jsx("h4",{className:"font-medium mr-2",children:"Global nameservers"}),e.jsxs("div",{className:"flex items-center space-x-2 ml-auto",children:[e.jsxs("label",{className:S("flex items-center cursor-pointer font-medium select-none space-x-1",{"text-text-disabled":n,"text-text-muted":!n}),htmlFor:"fallback",children:[e.jsx(O,{content:e.jsxs(e.Fragment,{children:[e.jsx("p",{children:"When enabled, use the DNS servers listed below to resolve names outside the tailnet."}),e.jsxs("p",{children:["When disabled (default), devices will prefer their local DNS configuration."," ",e.jsx(q,{kbTopic:"Learn more about global nameservers",url:"https://tailscale.com/kb/1054/dns#global-nameservers"})]})]}),children:e.jsx(Xe,{className:"relative -top-0.5 inline-block",size:"1em"})}),e.jsx("span",{children:"Override DNS servers"})]}),e.jsx(O,{content:p&&Z,children:e.jsx(ne,{id:"fallback",sizeVariant:"small",disabled:n||p,checked:!i,onChange:()=>{j({type:"toggle:resolvers",to:i?"global":"fallback"})}})})]})]}),e.jsxs("div",{className:l,children:[(i||n)&&e.jsx(re,{className:"-mb-px",route:{resolver:"Local DNS settings"},locked:!0,disabled:!0,readonly:p}),!n&&e.jsx(Oe,{resolvers:h.resolvers,fallback:i,readonly:p,onEdit:c,onEditNextDNS:m,onEditControlD:x,onDelete:u})]})]})]}),e.jsx(O,{content:p&&Z,children:t?e.jsx(T,{className:"mt-5 flex items-center justify-center",onClick:()=>c({resolver:""}),disabled:N||p,sizeVariant:"medium",children:"Add nameserver"}):e.jsxs(H,{side:"bottom",align:"start",asChild:!0,disabled:N||p,onCloseAutoFocus:o=>o.preventDefault(),trigger:e.jsx(T,{className:"mt-5 mr-2 flex items-center justify-center",disabled:N||p,sizeVariant:"medium",suffixIcon:e.jsx(be,{className:"ml-2",size:"1em",strokeWidth:"2.2"}),children:"Add nameserver"}),children:[!a.hasDOHServer&&ue.map(o=>e.jsxs(H.Item,{hidden:!f||h.providers.includes(o),onSelect:()=>f&&f(o),children:[e.jsxs("span",{className:"",children:[o," Public DNS"]}),e.jsx("span",{className:"inline-block ml-8 text-text-muted float-right tabular-nums",children:V[o][0]})]},o)),e.jsxs(H.Item,{hidden:a.hasDOHServer,onSelect:()=>m({resolver:""}),children:[e.jsx("span",{className:"",children:"NextDNS"}),e.jsx("span",{className:"inline-block ml-8 text-text-muted float-right tabular-nums",children:"DoH"})]},"NextDNS"),b.featureControlD&&e.jsxs(H.Item,{hidden:a.hasDOHServer,onSelect:()=>x({resolver:""}),children:[e.jsx("span",{className:"",children:"Control D"}),e.jsx("span",{className:"inline-block ml-8 text-text-muted float-right tabular-nums",children:"DoH"})]},"Control D"),!a.hasDOHServer&&e.jsx(H.Separator,{}),e.jsx(H.Item,{hidden:!u,onSelect:()=>c({resolver:""}),children:"Custom…"})]})})]})}function Yt({domain:s,readonly:a,config:i,onEdit:c,onDelete:u,routeCardClasses:f}){return e.jsxs("div",{className:S("DNSDomainGroup py-3 -mx-3 px-3 rounded-md"),children:[e.jsxs("header",{className:"flex items-center mb-1",children:[e.jsx("div",{className:"py-1 px-2 -ml-2",children:e.jsx(Je,{className:"relative -top-px text-text-disabled",strokeWidth:"1.8",size:"1.2em"})}),e.jsx("h4",{className:"font-medium mb-1 mr-2",children:s}),e.jsx("div",{className:"space-x-2 mb-1",children:e.jsx(Ee,{})})]}),e.jsx("div",{className:f,children:e.jsx(Oe,{domain:s,resolvers:i.routes[s]?Te(i.routes[s]).resolvers:[],readonly:a,onEdit:c,onDelete:u})})]})}function Me(){const{data:s,error:a,setTailnetSettings:i}=ie(),[c,u]=y.useState(!1);function f(){return u(!0),i({httpsEnabled:!0},"HTTPS enabled").then(()=>{u(!1)})}function m(){return u(!0),i({httpsEnabled:!1},"HTTPS disabled").then(()=>{u(!1)})}return{data:s,error:a,isPosting:c,enableHTTPS:f,disableHTTPS:m}}const Ut="text-sm break-words bg-gray-200 dark:bg-gray-900 px-1 rounded";function _t(s){const{open:a,onOpenChange:i}=s,{isPosting:c,enableHTTPS:u}=Me(),{data:f}=K();return e.jsx(P,{open:a,title:"Enable HTTPS",onOpenChange:i,children:e.jsxs(P.Form,{submitButton:"Enable",loading:c,disabled:c,cancelButton:!0,onSubmit:()=>u().then(()=>i(!1)),children:[e.jsxs("p",{className:"mb-6",children:["The name of any machine for which you obtain a HTTPS certificate will be published in a public ledger from which it cannot be removed."," ",e.jsx(q,{kbTopic:"enabling HTTPS",url:"https://tailscale.com/kb/1153/enabling-https"})]}),e.jsxs("p",{className:"mb-6",children:["The machine name includes your tailnet name, which is used to obfuscate your organization’s name (example:"," ",e.jsxs("code",{className:Ut,children:["machine-name.",f?.tcd]}),")."," "]})]})})}function Qt(s){const{open:a,onOpenChange:i}=s,{isPosting:c,disableHTTPS:u}=Me();return e.jsx(P,{title:"Disable HTTPS",open:a,onOpenChange:i,children:e.jsx(P.Form,{destructive:!0,autoFocus:"cancel",loading:c,disabled:c,cancelButton:!0,submitButton:"Disable",onSubmit:()=>u().then(()=>i(!1)),children:e.jsx("p",{children:"Certificates will no longer be able to be generated for machines in your tailnet. Links and connections that rely on HTTPS URLs will no longer work."})})})}function Gt(){const[s,a]=y.useState("none"),{data:i}=ie(),{access:c}=we(je.NetworkingSettings),f=!De(c);return e.jsxs(e.Fragment,{children:[e.jsx(O,{content:f&&Z,children:i?.httpsEnabled?e.jsx(T,{onClick:()=>a("disable-dialog"),sizeVariant:"medium",disabled:f,children:"Disable HTTPS..."}):e.jsx(T,{onClick:()=>{a("enable-dialog")},sizeVariant:"medium",disabled:f,children:"Enable HTTPS..."})}),e.jsx(Qt,{open:s==="disable-dialog",onOpenChange:m=>a(m?"disable-dialog":"none")}),e.jsx(_t,{open:s==="enable-dialog",onOpenChange:m=>a(m?"enable-dialog":"none")})]})}function Kt(){const{mutate:s}=Se(),{data:a,error:i}=ye("/searchdomains"),c=G(!1),u=te();function f(x){return c.setTrue(),ee.post("/searchdomains",x).then(N=>(c.setFalse(),s("/searchdomains",N.data.data),N.data.data)).catch(N=>{const j=N.response&&N.response.data&&N.response.data.error?"Failed: "+N.response.data.error:"Failed to set search domains.";c.setFalse(),u.show({message:j,variant:"danger"})})}function m(x){const N={optimisticData:x};s("/searchdomains",f(x),N)}return{data:a,error:i,isPosting:c.value,setData:m}}function Xt(s){const[a,i]=y.useState(""),c=()=>{s.onOpenChange(!1),i("")};function u(m){const{value:x,selectionStart:N,selectionEnd:j}=m.target,p=x.toLowerCase().replaceAll(/[^\d.a-z-]/g,"-").replaceAll(/-+/g,"-");m.target.value=p,m.target.selectionStart=N,m.target.selectionEnd=j,i(p)}const f=()=>{const m=s.data?.searchDomains||[];s.setData({searchDomains:[...m,a]}),c()};return e.jsx(P,{open:s.open,trigger:s.trigger,title:"Add search domain",restoreFocus:!1,onOpenChange:s.onOpenChange,children:e.jsxs(P.Form,{loading:s.isPosting,onSubmit:f,cancelButton:{onClick:c},submitButton:"Add search domain",disabled:a.length===0,children:[e.jsx(_,{placeholder:"foo.example.com",onChange:u,value:a,disabled:s.isPosting}),e.jsx("div",{className:"text-text-muted mt-2",children:"The search domain can only contain alphanumeric lowercase characters, hyphens, and periods."})]})})}function Jt(s){const{readonly:a}=s,{data:i}=Ze(),c=K(),{data:u,error:f,isPosting:m,setData:x}=Kt(),N=G(!1),j=(n,l,r)=>{const o=[...n],[d]=o.splice(l,1);return o.splice(r,0,d),o},p=i?.magicDNS?1:0,b=n=>{if(!n.destination)return;const l=n.source.index-p,r=n.destination.index-p,o=j(u?.searchDomains||[],l,r);x({searchDomains:o})},w=n=>{const l=[...u?.searchDomains||[]];l.splice(n-p,1),x({searchDomains:l})},h=n=>n{const n=[];return c.data&&i?.magicDNS&&n.push(c.data.tcd),n.push(...u?.searchDomains||[]),n.length===0?e.jsx(oe,{empty:!0,children:e.jsx(ae,{description:"No custom DNS search domains"})}):e.jsx(Dt,{onDragEnd:b,children:e.jsx(St,{droppableId:"search-domains2",type:"search-domains2",children:l=>e.jsxs("div",{...l.droppableProps,ref:l.innerRef,className:"border divide-y rounded-md overflow-hidden",children:[n.map((r,o)=>e.jsx(yt,{draggableId:r,index:o,isDragDisabled:a||h(o),children:(d,v)=>e.jsx("div",{ref:d.innerRef,className:S("bg-bg-base",{"border-none":v.isDragging}),...d.draggableProps,children:e.jsxs("div",{className:S("flex gap-2 py-2 items-center relative rounded-none shadow-transparent transition-all duration-500",{"px-2":n.length>1,"px-4":n.length===1,"!shadow-drag-outline !rounded-md !transition-none":v.isDragging,"hover:cursor-grab":!a&&!h(o)}),...d.dragHandleProps,children:[e.jsxs("div",{className:"flex flex-1 gap-2 items-center icon-parent",children:[e.jsx(et,{className:S("text-text-disabled",{invisible:a||h(o),hidden:n.length===1})}),e.jsx("div",{className:S("font-medium",{"text-text-muted":h(o)}),children:r})]}),!a&&!h(o)&&e.jsx(T,{onClick:()=>w(o),variant:"minimal",intent:"danger",sizeVariant:"medium",className:"absolute right-1",children:"Remove"})]})})},r)),l.placeholder]})})})};return e.jsxs(e.Fragment,{children:[u===void 0?e.jsx(Y,{}):e.jsx(e.Fragment,{children:f?e.jsx(Y,{error:{message:"Failed to load search domains. Refresh the page to retry."}}):t()}),e.jsx(Xt,{open:N.value,trigger:e.jsx(T,{className:"mt-5",sizeVariant:"medium",disabled:a,children:"Add search domain..."}),onOpenChange:n=>N.set(n),isPosting:m,data:u,setData:x})]})}function Zt(s){return{id:s.id,name:s.name,user:s.user,tags:s.allowedTags||[],ipnVersion:s.ipnVersion,os:s.os,osVersion:s.osVersion||"",machine:s,addrs:s.addresses||[]}}function es(s){return s.map(Zt)}function ts({machines:s,onSelected:a,onInput:i,onOpenChange:c}){const[u,f]=y.useState(""),[m,x]=y.useState(!1),[N,j]=y.useState(""),p=y.useMemo(()=>{if(u==="")return[];const r=u.toLowerCase();return s.filter(o=>o.name.toLowerCase().includes(r)||o.user.includes(u)||o.tags?.some(v=>v.includes(r))||o.addrs?.some(v=>v.includes(r)))},[s,u]),{getMenuProps:b,getInputProps:w,highlightedIndex:h,getItemProps:t,selectedItem:n}=z({items:p,itemToString:r=>r?.name||"",defaultHighlightedIndex:0,selectedItem:null,inputValue:u,onIsOpenChange:({isOpen:r})=>r===void 0?void 0:c?.(r),stateReducer(r,o){const{changes:d,type:v}=o;switch(v){case z.stateChangeTypes.InputKeyDownEnter:case z.stateChangeTypes.ItemClick:return{...d,isOpen:!1,highlightedIndex:0};default:return d}},onStateChange({type:r,inputValue:o,selectedItem:d}){switch(r){case z.stateChangeTypes.InputKeyDownEnter:case z.stateChangeTypes.ItemClick:{d&&(a(d),l(""));break}case z.stateChangeTypes.InputChange:{l(o||"");break}}}});function l(r){f(r||""),x(Ie(r)),j(r)}return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx(ke,{className:"flex-1",name:"query",autoCorrect:"off",autoComplete:"off",autoCapitalize:"off",placeholder:"Enter IPs or search by device name","aria-autocomplete":"list","aria-controls":"machine-listbox","aria-expanded":p.length>0,"aria-haspopup":"listbox","aria-label":"Search for a device by name or IP",onClearClick:()=>{f("")},...w()}),e.jsx(T,{type:"button","aria-label":"Add ip addresses of selected machine",onClick:()=>{f(""),i(N)},disabled:!m,children:"Add"})]}),u.length>0&&p.length>0&&e.jsx(tt,{className:"max-w-80",open:u.length>0,align:"start",asChild:!1,children:null,onOpenAutoFocus:r=>r.preventDefault(),content:e.jsx("ul",{className:"mt-1 max-h-80 overflow-auto rounded-md",...b({},{suppressRefError:!0}),children:p.length===0?e.jsx(e.Fragment,{}):p.map((r,o)=>e.jsx("li",{tabIndex:0,className:S("w-full",at,{"cursor-pointer bg-bg-menu-item-hover":o===h||n===r}),...t({item:r,index:o}),children:e.jsxs("div",{className:"flex flex-col justify-between p-1 leading-tight",children:[e.jsx("div",{className:"flex items-center font-semibold",children:r.name}),e.jsx("div",{className:"flex items-center text-text-muted",children:r.user&&e.jsxs("p",{children:[r.user," · ",st(r.os)]})}),e.jsx("div",{children:!r.user&&r.tags&&r.tags.map(d=>e.jsx(nt,{tag:d,className:"mr-1 mt-1"},d))}),r.addrs&&e.jsx("div",{className:"flex items-center text-text-muted",children:r.addrs.join(", ")})]})},`${r.id}-${o}`))})})]})}const pe=255;function ss(s){const a=s.editableRecord?.baseName,[i,c]=y.useState(s.editableRecord?.baseName||""),[u,f]=y.useState(s.editableRecord?.comment||""),m=s.editableRecord?.addrs||[],[x,N]=y.useState(m),[j,p]=y.useState(s.action==="edit"),[b,w]=y.useState(t(s.editableRecord?.baseName||"")?"This domain prefix is already in use.":void 0),h=()=>{s.onOpenChange(!1),c(""),f(""),p(!1),w(void 0),N([])};function t(g){if(s.action==="edit"&&g===a)return!1;for(const D of s.records||[])if(D.baseName===g)return!0;return!1}function n(g){const{value:D}=g.target;if(t(D))p(!1),w("Name is already in use");else{const{isValid:C,error:M}=rt(D);p(C),w(M)}c(D.toLocaleLowerCase())}function l(g){if(!Ie(g))return;const D=it(g);let k=x.slice();for(const C of D)k.includes(C)||(k=k.concat(C));N(k)}function r(g){N(x.filter(D=>D!==g))}function o(g){l(g.machine.addresses.join(","))}function d(g){const{value:D}=g.target;D.length>pe?f(D.slice(0,pe)):f(D)}const v=()=>{if(!I())return;const g={baseName:i,addrs:x.slice(),comment:u};s.editableRecord&&a?s.editStaticRecord(a,g):s.addStaticRecord(g),h()};function I(){return j&&x.length>0&&!s.isPosting}return e.jsx(P,{open:s.open,trigger:s.trigger,title:xe(s.action),restoreFocus:!1,onOpenChange:g=>{g||h(),s.onOpenChange(g)},children:e.jsx(P.Form,{loading:s.isPosting,onSubmit:v,cancelButton:{onClick:h},submitButton:xe(s.action),disabled:!I(),children:e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(X,{label:"Name",description:"DNS prefix and ID for this record.",error:b,help:e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:i}),".",s.tailnetData?.tcd]}),children:e.jsx(_,{onChange:n,value:i,disabled:s.isPosting})}),e.jsxs("div",{children:[e.jsx(X,{label:"Destination",description:"Where you would like this record to point to.",children:e.jsx(ts,{machines:es(s.machineData||[]),onSelected:o,onInput:l})}),x.length>0&&e.jsxs(oe,{className:"flex flex-col divide-y mt-1.5",noPadding:!0,children:[" ",x.map((g,D)=>e.jsxs("div",{className:"flex items-center content-between gap-2 py-1 pl-3 pr-1",children:[e.jsx("div",{className:"flex-1",children:e.jsx(Ce,{ip:g})}),e.jsx(T,{type:"button",variant:"minimal",sizeVariant:"small","aria-label":`Remove IP address ${g}`,onClick:()=>r(g),intent:"danger",children:"Remove"})]},D))]})]}),e.jsx(X,{label:"Notes",description:"Optional notes describing what the record is for.",children:e.jsx(_,{onChange:d,value:u,disabled:s.isPosting})})]})})})}function xe(s){return s==="add"?"Add record":"Edit record"}function ns({data:s,query:a=""}){const{results:i,queryWithoutFilters:c}=ot({data:s,query:a,simpleFilters:rs,paramFilters:is}),{results:u}=lt({data:i,query:c,options:as});return{results:u}}const as={threshold:0,distance:80,ignoreLocation:!0,keys:[{name:"baseName",weight:.8},{name:"recordInfo.addrs",weight:.5},{name:"recordInfo.comment",weight:.5}]},rs={"has:baseName":s=>s.baseName!==void 0,"has:recordInfo.comment":s=>s.comment!==void 0},is={basename:(s,a)=>{const i=s.baseName?.toLowerCase()??"";return a.some(c=>i.includes(c.toLowerCase()))},comment:(s,a)=>{const i=s.comment?.toLowerCase()??"";return a.some(c=>i.includes(c.toLowerCase()))}};function os(s){return s?.records?Object.entries(s.records).map(([a,i])=>({baseName:a,addrs:i.addrs,comment:i.comment})):[]}function ls(){const{mutate:s}=Se(),{data:a,error:i}=ye("/public/tailnet/-/static-records"),c=G(!1),u=te();async function f(p){c.setTrue(),await ee.put(`/public/tailnet/-/static-records/${p.baseName}`,JSON.stringify(p)).then(b=>{c.setFalse(),s("/public/tailnet/-/static-records",b.data.data)}).catch(b=>{const w=b.response&&b.response.data&&b.response.data.error?"Failed: "+b.response.data.error:"Failed to add record.";c.setFalse(),u.show({message:w,variant:"danger"})})}function m(p){return c.setTrue(),ee.delete(`/public/tailnet/-/static-records/${p.baseName}`).then(()=>{c.setFalse()}).catch(b=>{const w=b.response&&b.response.data&&b.response.data.error?"Failed: "+b.response.data.error:"Failed to delete record.";c.setFalse(),u.show({message:w,variant:"danger"})})}function x(p){s("/public/tailnet/-/static-records",f(p))}function N(p){s("/public/tailnet/-/static-records",m(p))}function j(p,b){x(b),p!==b.baseName&&N({baseName:p})}return{data:os(a),error:i,isPosting:c.value,addStaticRecord:x,removeStaticRecord:N,editStaticRecord:j}}function cs(s){const a=s.data||[],i=te(),{query:c,setQuery:u,tmpQuery:f,setTmpQuery:m}=dt(),{results:x}=ns({data:a??[],query:c});function N(I){m(I.target.value)}function j(){u(""),m("")}function p(I){I.preventDefault(),u(f)}const b=S(ut.cellExpand,"flex items-center"),w=S(b,"@md:w-1/6 w-1/3"),h=S(b,"@md:w-1/4 w-1/2"),t=S(b,"w-1/2 hidden @md:table-cell"),n=S(b,"@md:w-1/12 w-1/6"),l="text-elipsis items-center",r=S(l,"break-words @md:w-1/6 w-1/3"),o=S(l,"truncate @md:w-1/4 w-1/2"),d=S(l,"break-words w-1/2 hidden @md:table-cell"),v="flex justify-end ml-auto @md:ml-0 relative justify-items-end items-center @md:items-start @md:w-1/12 w-1/6";return a.length===0||a===void 0?e.jsx(e.Fragment,{children:e.jsx(oe,{className:"flex flex-col mt-10 items-center p-10",elevated:!0,children:e.jsx(ae,{title:"Add a record",description:"Records let you create virutal IPs and DNS records that work inside your tailnet.",action:e.jsx(T,{intent:"primary",onClick:()=>s.onShowEditor("add",void 0),children:"Add record…"})})})}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex mb-4 @sm:flex-shrink items-center gap-4 w-full",children:[e.jsx("form",{onSubmit:p,className:"flex-1",children:e.jsx(ke,{type:"text",name:"query","aria-label":"Search by name, destination or notes",placeholder:"Search by name, destination, notes...",onChange:N,onClearClick:j,value:f})}),e.jsx(T,{"aria-label":"Add a new record",onClick:()=>s.onShowEditor("add",void 0),children:"Add record…"})]}),e.jsx("div",{className:"mb-4 w-full",children:e.jsxs("table",{className:"tb w-full",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{className:w,children:"Name"}),e.jsx("th",{className:h,children:"Destination"}),e.jsx("th",{className:t,children:"Notes"}),e.jsx("th",{className:n})]})}),e.jsx("tbody",{children:x.length>0?x?.map(I=>e.jsxs("tr",{children:[e.jsxs("td",{className:r,children:[e.jsxs("strong",{children:[I.baseName,"."]}),e.jsx("span",{className:"text-text-disabled",children:s.tailnetData?.tcd})]}),e.jsx("td",{className:o,children:(I.addrs?.length||0)>0?I.addrs?.map(g=>e.jsx("div",{children:e.jsx("span",{children:e.jsx(Ce,{ip:g})},g)},g)):e.jsx("span",{className:"text-text-disabled",children:"No routes"})}),e.jsx("td",{className:d,children:I.comment}),e.jsx("td",{className:v,children:ds(I,s,i)})]},I.baseName)):e.jsx("tr",{children:e.jsx("td",{className:"flex-auto max-w-full px-4 my-5 text-center",children:e.jsx(ae,{description:"No records match your search",action:e.jsx("a",{href:"#",className:"link",onClick:I=>{I.preventDefault(),j()},children:"Clear search"})})})})})]})})]})}function ds(s,a,i){return e.jsx(ve,{ariaLabel:`Quick actions for ${s.baseName}`,items:[{type:"item",label:"Copy routes",onSelect:()=>{s.addrs!==void 0&&he(s.addrs.join(", ")).then(()=>i.show({message:"Copied routes to clipboard"})).catch(()=>i.show({message:"Failed to copy routes to clipboard",variant:"danger"}))}},{type:"item",label:"Copy name",onSelect:()=>{s.baseName!==void 0&&he(s.baseName).then(()=>i.show({message:"Copied name to clipboard"})).catch(()=>i.show({message:"Failed to copy name clipboard",variant:"danger"}))}},{type:"separator"},{type:"item",label:"Edit…",onSelect:()=>a.onShowEditor("edit",s)},{type:"separator"},{type:"item",intent:"danger",label:"Delete…",onSelect:()=>a.onDelete(s)}],side:"right"})}function us(){const{data:s,isPosting:a,addStaticRecord:i,removeStaticRecord:c,editStaticRecord:u}=ls(),{data:f}=K(),{data:m}=ct(),x=G(!1),[N,j]=y.useState(void 0),[p,b]=y.useState("add");function w(h,t){j(t),b(h),x.set(!0)}return e.jsxs(e.Fragment,{children:[x.value&&e.jsx(ss,{action:p,open:x.value,trigger:void 0,onOpenChange:h=>x.set(h),isPosting:a,editableRecord:N,addStaticRecord:i,editStaticRecord:u,machineData:m?.machines,tailnetData:f,records:s}),e.jsx(cs,{onShowEditor:(h,t)=>w(h,t),onDelete:h=>c(h),data:s,tailnetData:f,trigger:void 0})]})}function hs(s){const{tcd:a}=s,[i,...c]=a.split(".");return e.jsxs(e.Fragment,{children:[i,e.jsxs("span",{className:"text-text-disabled",children:[".",c.join(".")]})]})}function ms(s){const{open:a,onOpenChange:i}=s,{data:c,offers:u,hasPostingError:f,generateTCDOffers:m,setTCD:x,isPosting:N}=K(),{data:j}=ie(),p=G(!1),[b,w]=y.useState(),h=()=>{f.setFalse(),w(void 0),m()},t=y.useCallback(()=>{x(b).then(()=>i(!1)).then(p.setFalse).catch(()=>w(void 0))},[b,i,x,p]),n=()=>{switch(u?.offerType){case"new":return"Select a generated name or re-roll to get a fresh set. If you use your tailnet name in HTTPS certificates, it will be bound to your account and you will no longer be able to select a new fun name.";case"reoffer":return"Select a generated name or re-roll to get a fresh set. If you select a new fun tailnet name, your previous fun name will be released and available to others. If you use your tailnet name in HTTPS certificates, it will be bound to your account and you will no longer be able to select a new fun name.";case"locked":return"You can revert your tailnet’s name to:";default:return"Select a tailnet name:"}};return p.value?e.jsx(P,{title:"Rename "+c?.tcd,open:a,onOpenChange:i,children:e.jsxs(P.Form,{disabled:b===void 0||b.tcd===c?.tcd,loading:N,cancelButton:!0,submitButton:"Rename tailnet",onSubmit:t,children:[e.jsxs("p",{className:"mb-2",children:[n()," ",e.jsx(q,{kbTopic:"tailnet name",url:"https://tailscale.com/kb/1217/tailnet-name"})]}),u?.tcds.length===0?e.jsx(Pe,{intent:"error",icon:!1,children:"Failed to load tailnet name options. Please re-roll or try again later."}):e.jsx(fs,{offers:u?.tcds,selectedTCDOffer:b,setSelectedTCDOffer:w,hasPostingError:f.value}),f.value&&e.jsx("p",{className:S(E.fieldErrorText,"mt-2"),children:"Unable to register tailnet name. Please re-roll for new options."}),(u?.offerType==="new"||u?.offerType==="reoffer")&&e.jsx(T,{type:"button",className:"mt-5 mb-5 flex items-center",disabled:N,onClick:()=>h(),prefixIcon:e.jsx(ht,{}),children:"Re-roll options"})]})}):e.jsx(P,{open:a,title:"Rename "+c?.tcd,onOpenChange:i,children:e.jsxs(P.Form,{submitButton:{children:"I understand, let me rename the tailnet",className:"w-full"},onSubmit:()=>m().then(p.setTrue),children:[e.jsxs("p",{className:"mb-6",children:["Renaming your tailnet may break existing links to devices in your tailnet."," ",e.jsx(q,{kbTopic:"tailnet name",url:"https://tailscale.com/kb/1217/tailnet-name"})]}),j?.httpsEnabled&&e.jsxs("p",{className:"",children:["You will need to reissue HTTPS certificates using the new tailnet name. The name of any machine for which you obtain a HTTPS certificate, including the new tailnet name, will be published in a public ledger from which it cannot be removed."," "]})]})})}function fs(s){const{selectedTCDOffer:a,setSelectedTCDOffer:i,offers:c,hasPostingError:u}=s;return e.jsx("div",{className:"mb-5",children:c?.map(f=>e.jsx(ps,{offer:f,setSelected:()=>i(f),checked:f.tcd===a?.tcd,hasPostingError:u},f.tcd))})}function ps(s){const{setSelected:a,offer:i,checked:c,hasPostingError:u}=s;return e.jsxs("label",{className:S("flex mt-1",{"text-text-muted":u}),children:[e.jsx("input",{type:"radio",name:"tcd-rad",className:"radio mt-1 mr-1",checked:c,value:i.tcd,disabled:u,onChange:()=>{a()}}),e.jsx(hs,{tcd:i.tcd})]})}function xs(){const[s,a]=y.useState(!1),{data:i,error:c}=K(),{access:u}=we(je.NetworkingSettings),m=!De(u)||i===void 0||c;return e.jsxs(e.Fragment,{children:[i===void 0?e.jsx(Y,{}):e.jsxs(e.Fragment,{children:[c?e.jsx(Y,{error:{message:"Failed to load tailnet name. Refresh the page to retry."}}):e.jsx(mt,{text:i.tcd,className:"w-full max-w-sm",prompt:!1}),e.jsx(T,{className:"mt-5",onClick:()=>{a(!0)},sizeVariant:"medium",disabled:m,children:"Rename tailnet..."})]}),e.jsx(ms,{open:s,onOpenChange:a})]})}const Le={isPosting:!1,isPostingMagicDNS:!1};function gs(s,a){switch(a.type){case"set-loading":return{...s,isPosting:!0};case"set-loading-magic-dns":return{...s,isPostingMagicDNS:!0};case"done-loading":return{...s,...Le};case"route:edit":return{...s,currentRoute:a.route};case"route:edit-nextdns":return{...s,currentRoute:a.route,triggeredFrom:"nextdns"};case"route:edit-control-d":return{...s,currentRoute:a.route,triggeredFrom:"controld"};case"route:edit-close":return{...s,currentRoute:void 0,triggeredFrom:void 0};case"confirm":return{...s,confirm:a.data};case"confirm-cancel":return{...s,confirm:void 0};default:return Re(a)}}function Ss({readonly:s}){const{data:a,error:i,mutate:c}=ft(),{data:u}=Ne(),f=te(),[m,x]=y.useReducer(gs,Le),{variant:N}=pt("replace-learn-more-ctas-with-descriptive-ctas",!0),j=g=>{c(D=>D?Nt(D,g):void 0,!1).then(D=>{D&&(wt(a,D)||ee.post("/dns",D).then(k=>k.data.data).then(k=>{switch(x({type:"done-loading"}),!0){case(!a?.magicDNS&&k.magicDNS):{f.show({message:"Enabled MagicDNS"});break}case(a?.magicDNS&&!k.magicDNS):{f.show({message:"Disabled MagicDNS"});break}}c(k,!1)}).catch(k=>{const C=k.response?.data?.error;x({type:"done-loading"}),f.show({message:"Failed to update DNS settings"+(C===void 0?"":": "+C),variant:"danger"}),c()}))})},p=(g,D,k,C)=>{const M={type:"route:update",route:g,existing:D},F=g.fallback?a?.fallbackResolvers:a?.resolvers;k&&F&&F.length>0?x({type:"confirm",data:{type:"enable-doh",warning:"You can’t mix NextDNS with other global resolvers. Are you sure you want to delete all your other resolvers?",title:"Delete other global resolvers?",actions:[{type:"route:remove",routes:F.map(U=>({resolver:U.address,fallback:g.fallback}))},M]}}):C&&F&&F.length>0?x({type:"confirm",data:{type:"enable-doh",warning:"You can’t mix Control D with other global resolvers. Are you sure you want to delete all your other resolvers?",title:"Delete other global resolvers?",actions:[{type:"route:remove",routes:F.map(U=>({resolver:U.address,fallback:g.fallback}))},M]}}):(j(M),n(g,D))},b=()=>{if(!(!a||!m.confirm)){switch(m.confirm.type){case"disable-magic-dns":case"enable-doh":{m.confirm.actions.forEach(g=>{j(g)});break}default:return Re(m.confirm.type)}w()}},w=()=>x({type:"confirm-cancel"}),h=g=>x({type:"route:edit",route:g}),t=(g,D)=>{j({type:"route:add",route:{resolver:V[g][0],fallback:D}})},n=(g,D)=>{if(W[g.resolver]&&(!D||g.resolver!==D.resolver)){const k=W[g.resolver];f.show({message:`${g.resolver} is part of the ${k} Public DNS, so we’ve gone ahead and added the whole set for you.`,timeout:8e3})}},l=g=>{a&&j({type:"route:remove",routes:g})},r=()=>{if(a){if(a.magicDNS){x({type:"confirm",data:{type:"disable-magic-dns",warning:"Users of your network will no longer be able to use short names to access devices over Tailscale.",title:"Disable MagicDNS?",actions:[{type:"magicdns:disable"}]}});return}j({type:"magicdns:enable"})}},o=g=>{x({type:"route:edit-nextdns",route:g})},d=g=>{x({type:"route:edit-control-d",route:g})};let v,I;if(i)v=e.jsx(Y,{error:i,className:"mt-6"});else if(a){const g=a.resolvers.length===0,D=[];a.magicDNS&&D.push("MagicDNS"),xt(a)&&D.push("Split DNS"),I=e.jsxs("div",{className:"mt-6",children:[e.jsx(B,{title:"Tailnet DNS name",description:"This unique name is used when registering DNS entries, sharing your device to other tailnets, and issuing TLS certificates.",kbLink:"https://tailscale.com/kb/1217/tailnet-name",children:e.jsx(xs,{})}),e.jsx(B,{title:"Apps",description:"Control device and user access to your third-party applications, without requiring any end user configuration.",kbLink:"https://tailscale.com/kb/1342/app-connectors-setup",children:e.jsx(gt,{to:"/admin/apps",children:"Manage in Apps"})}),e.jsxs(B,{title:"Nameservers",description:"Set the nameservers used by devices on your network to resolve DNS queries.",kbLink:"https://tailscale.com/kb/1054/dns",children:[e.jsx(vs,{warnings:a.warnings}),e.jsx(qt,{disabled:m.isPosting,config:a,useFallbackResolvers:g,onEdit:h,onAddPreset:C=>t(C,g),onTriggerNextDNS:o,onTriggerControlD:d,onDelete:l,dispatch:j,readonly:s})]}),e.jsx(B,{title:"Search Domains",description:"Set custom DNS search domains. With MagicDNS enabled, your tailnet domain is always the first search domain.",kbLink:"https://tailscale.com/kb/1054/dns/",children:e.jsx(Jt,{readonly:s})}),e.jsx(B,{title:"MagicDNS",description:"Automatically register domain names for devices in your tailnet. This lets you to use a machine’s name instead of its IP address.",kbLink:"https://tailscale.com/kb/1081/magic-dns",children:e.jsxs(e.Fragment,{children:[e.jsx(O,{content:s&&Z,children:e.jsx(T,{id:"enabled",disabled:m.isPosting||s,loading:m.isPostingMagicDNS,onClick:r,intent:a.magicDNS?"base":"primary",sizeVariant:"medium",children:a.magicDNS?"Disable MagicDNS…":"Enable MagicDNS"})}),e.jsx(P,{open:m.confirm!==void 0,onOpenChange:C=>C?void 0:w(),title:m.confirm?.title||"Confirmation needed",children:e.jsx(P.Form,{autoFocus:"cancel",destructive:!0,cancelButton:"Cancel",submitButton:m.confirm?.type==="disable-magic-dns"?"Disable MagicDNS":"Remove nameservers",onSubmit:b,children:m.confirm?.type===void 0?e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"mb-2",children:["Removing this nameserver will"," ",e.jsxs("strong",{children:["disable ",D.join(" and ")]}),", which currently need",D.length===1?"s":""," at least one global nameserver."]}),e.jsxs("p",{className:"mb-8",children:["Disabling"," ",D.length===1?D[0]:"these features"," ","may break domain names which users of your network rely on."]})]}):e.jsx("p",{className:"mb-8",children:m.confirm?.warning})})})]})}),u.featureHTTPS&&e.jsx(B,{title:"HTTPS Certificates",description:"Allow users to provision HTTPS certificates for their devices.",kbLink:"https://tailscale.com/kb/1153/enabling-https/",children:e.jsx(Gt,{})}),e.jsx(Bt,{open:m.currentRoute!==void 0,triggeredFrom:m.triggeredFrom,disabled:m.isPosting,initialValue:m.currentRoute,validateRoute:Ft(a),useFallbackResolvers:g,onSubmit:p,hasDOHServer:a.hasDOHServer,onOpenChange:C=>C?void 0:x({type:"route:edit-close"})})]});const k=e.jsx("div",{className:"flex-auto w-full",children:e.jsx(bs,{title:"Records",description:"Create virtual IPs and DNS records that only work inside your tailnet.",kbLink:"https://tailscale.com/kb/1054/dns",isBeta:!0,children:e.jsx(us,{})})});u.staticRecords?v=e.jsx("div",{className:"mt-6",children:e.jsx(bt,{tabs:[{id:"dns-overview",label:"Overview",content:I},{id:"dns-records",label:"Records",content:k}]})}):v=I}else v=e.jsx(Y,{loadingMessage:"Loading DNS settings…",className:"mt-6"});return e.jsx(vt,{className:"mb-24",title:"DNS",description:"Manage DNS and nameservers of your network.",learnMoreUrl:"https://tailscale.com/kb/1054/dns/",learnMoreLabel:N==="variant1"?"See how to configure DNS":void 0,children:v})}function B(s){const{title:a,description:i,kbLink:c,children:u,isBeta:f}=s;return e.jsxs("section",{className:"mb-10 max-w-2xl",children:[e.jsxs("header",{className:"mb-5",children:[e.jsxs("h2",{className:E.sectionTitle,children:[a,f&&e.jsx(Q,{className:"relative ml-2 -top-px",variant:"status",color:"yellow",children:"Beta"})]}),e.jsxs("p",{className:"mt-2",children:[i," ",c&&e.jsx(q,{kbTopic:a,url:c})]})]}),u]})}function bs(s){const{title:a,description:i,kbLink:c,children:u,isBeta:f}=s;return e.jsxs("section",{className:"mb-10",children:[e.jsxs("header",{className:"mb-5",children:[e.jsxs("h2",{className:E.sectionTitle,children:[a,f&&e.jsx(Q,{className:"relative ml-2 -top-px",variant:"status",color:"yellow",children:"Beta"})]}),e.jsxs("p",{className:"mt-2",children:[i," ",c&&e.jsx(q,{kbTopic:a,url:c})]})]}),u]})}function vs(s){const{warnings:a}=s;return a.length===0?null:e.jsx("div",{className:"space-y-3 mb-5",children:a.map(i=>{const c=Ns[i];return e.jsx(Pe,{intent:"warning",title:c.title,children:c.body},i)})})}const Ns={"racing-private":{title:"Inconsistent DNS lookups",body:e.jsxs(e.Fragment,{children:["Your tailnet uses both private and public global nameservers. This can"," ",e.jsx("a",{href:"https://tailscale.com/kb/1194/dns-resolver-order/",className:"link-underline",target:"_blank",rel:"noopener noreferrer",children:"cause inconsistent DNS lookup responses"}),". Fix this by removing public nameservers, or restricting private DNS queries to a search domain."]})},"nextdns-old-client":{title:"Upgrade older clients to use NextDNS nameservers",body:e.jsxs(e.Fragment,{children:["Your tailnet has older Tailscale clients which are unable to use the NextDNS nameservers and will fall back to system DNS settings. Fix this by"," ",e.jsx(jt,{className:"link-underline",href:"/admin/machines/?q=version:<1.32.0",children:"updating devices to v1.32.0 or greater"}),"."]})},"dohserver-others":{title:"NextDNS nameservers mixed with other nameservers",body:e.jsxs(e.Fragment,{children:["Your tailnet uses DOH (NextDNS or Control D) nameservers alongside other nameservers. This"," ",e.jsx("a",{href:"https://tailscale.com/kb/1218/nextdns/#use-nextdns-as-a-global-nameserver",className:"link-underline",rel:"noopener noreferrer",target:"_blank",children:"circumvents NextDNS’s privacy or parental controls"}),". Fix this by removing other nameservers."]})},"dohserver-multiple":{title:"Multiple NextDNS nameservers",body:e.jsxs(e.Fragment,{children:["Your tailnet has multiple DOH (NextDNS or Control D) global nameservers configured,which leads to unpredictable resolution results. Configure a single DOH global nameserver. If you want different devices to use different profiles, configure these in the tailnet policy file."," ",e.jsx("a",{href:"https://tailscale.com/kb/1218/nextdns/#use-different-nextdns-profiles-for-different-devices",className:"link-underline",rel:"noopener noreferrer",target:"_blank",children:"Learn more"})]})},"dohserver-split":{title:"NextDNS nameservers used with split DNS",body:e.jsx(e.Fragment,{children:"DOH (NextDNS or Control D) nameservers cannot be used with split DNS. Fix this by removing NextDNS/Control D nameservers from search domains."})},"only-ipv6":{title:"Missing IPv4 nameservers",body:e.jsx(e.Fragment,{children:"Your tailnet only specifies IPv6 nameservers. Some devices may not be able to resolve DNS queries without an IPv4 fallback. Fix this by adding an IPv4 nameserver."})},"omitted-invalid":{title:"Invalid nameservers omitted",body:e.jsx(e.Fragment,{children:"Your tailnet config contained invalid nameservers. They are omitted from this screen and will be deleted on save. Examples of invalid nameservers include loopback addresses, malformed IPs, or IPs with port numbers."})}};export{Ss as default};