1import{r as d,w as O}from"./chunk-LFPYN7LY-BFxOW0GP.js";import{j as e}from"./jsx-runtime-u17CrQMm.js";import{c as Y}from"./analytics-C7906a3W.js";import{b as U}from"./structured-data-BFMMei1x.js";import{M as K,P as H}from"./MarketingLayout-DDrv-W3y.js";import{P as D,a as _}from"./ProductTextMark-fefw6xuJ.js";import{a as J,E as Q}from"./xpf-BldPe2H6.js";import{E as w,M as p,b as u,d as T,D as V,e as M,B as x,A as R,H as q,S as N,c as Z,a as ee}from"./tokens-DvGGyUza.js";import"./CopyButton-CCdCdsnA.js";import{C as $,X as te}from"./XpfCustomerLogosSection-CbG2LiTW.js";import{a as se}from"./hooks-D-LcsWY0.js";import{R as S}from"./Reveal-B2jD4tGu.js";import"./tokens-C2m5-FTJ.js";const ae=(t,r,s)=>Math.min(s,Math.max(r,t));function ne(t,r){return Math.round(t/r)*r}function z({label:t,glyph:r,onPress:s,disabled:o,side:n}){const[l,c]=d.useState(!1);return e.jsx("button",{type:"button","aria-label":t,disabled:o,onClick:s,onMouseEnter:()=>c(!0),onMouseLeave:()=>c(!1),className:"shrink-0 grid place-items-center",style:{width:"52px",alignSelf:"stretch",color:o?V:l?u:p,backgroundColor:l&&!o?"rgba(255,255,255,0.06)":"transparent",cursor:o?"not-allowed":"pointer",borderRight:n==="left"?`1px solid ${T}`:void 0,borderLeft:n==="right"?`1px solid ${T}`:void 0,transition:`background-color 0.15s ${w}, color 0.15s ${w}`},children:e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14","aria-hidden":!0,focusable:"false",children:e.jsx("path",{d:r==="minus"?"M2 7h10":"M2 7h10M7 2v10",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round"})})})}function oe({id:t,label:r,value:s,min:o,max:n,step:l,prefix:c,onChange:h}){const[a,m]=d.useState(null),[g,y]=d.useState(!1),E=d.useRef(null),k=i=>h(ae(i,o,n)),v=i=>{m(null),k(ne(s+i*l,l)),E.current?.focus()},L=a??s.toLocaleString("en-GB");return e.jsxs("div",{className:"flex items-stretch overflow-hidden",style:{height:"48px",borderRadius:"12px",backgroundColor:"rgba(255,255,255,0.05)",border:`1px solid ${g?"rgba(31,158,255,0.45)":"rgba(255,255,255,0.10)"}`,boxShadow:g?"0 0 0 3px rgba(31,158,255,0.12)":"none",transition:`border-color 0.15s ${w}, box-shadow 0.15s ${w}`},children:[e.jsx(z,{side:"left",glyph:"minus",label:`Decrease ${r}`,disabled:s<=o,onPress:()=>v(-1)}),e.jsxs("div",{className:"flex-1 flex items-center justify-center gap-0.5 min-w-0 px-2",children:[c&&e.jsx("span",{"aria-hidden":!0,style:{fontSize:"16px",fontWeight:420,color:p},children:c}),e.jsx("input",{ref:E,id:t,type:"text",inputMode:"numeric",autoComplete:"off",role:"spinbutton","aria-valuenow":s,"aria-valuemin":o,"aria-valuemax":n,value:L,onFocus:i=>{y(!0),i.currentTarget.select()},onChange:i=>{const f=i.target.value;m(f);const j=Number(f.replace(/[,\s]/g,""));f.trim()!==""&&Number.isFinite(j)&&j>=o&&j<=n&&h(j)},onBlur:i=>{y(!1);const f=Number(i.target.value.replace(/[,\s]/g,""));k(Number.isFinite(f)&&i.target.value.trim()!==""?f:o),m(null)},onKeyDown:i=>{i.key==="ArrowUp"?(i.preventDefault(),v(1)):i.key==="ArrowDown"?(i.preventDefault(),v(-1)):i.key==="Enter"&&i.currentTarget.blur()},size:Math.max(2,L.length),style:{width:"auto",minWidth:"2ch",textAlign:"center",fontSize:"16px",fontFamily:"var(--font-sans)",fontWeight:420,color:u,backgroundColor:"transparent",border:"none",outline:"none"}})]}),e.jsx(z,{side:"right",glyph:"plus",label:`Increase ${r}`,disabled:s>=n,onPress:()=>v(1)})]})}const I=1,B=2.5,A=.3,P=.4,G=220,X=G/12;function re(t){const r=Math.max(0,t.xamlFiles),s=Math.max(1,t.engineers),o=Math.max(0,t.dayRate),n=t.suites>0,l=r*I,c=r*B,h=l*(1+(n?A:0)),a=c*(1+(n?P:0)),m=h*o,g=a*o;return{baseDaysLow:l,baseDaysHigh:c,totalDaysLow:h,totalDaysHigh:a,costLow:m,costHigh:g,contingencyLow:(h-l)*o,contingencyHigh:(a-c)*o,monthsLow:h/s/X,monthsHigh:a/s/X,hasContingency:n}}function b(t){return`â¬${Math.round(t).toLocaleString("en-GB")}`}function F(t){return t<2?`${t.toFixed(1)}`:`${Math.round(t)}`}function C({label:t,hint:r,value:s,min:o,max:n,step:l,prefix:c,onChange:h}){const a=`field-${t.replace(/\s+/g,"-").toLowerCase()}`;return e.jsxs("div",{children:[e.jsx("label",{htmlFor:a,className:"block mb-2.5",style:{fontSize:"15px",fontWeight:420,color:u},children:t}),e.jsx(oe,{id:a,label:t.toLowerCase(),value:s,min:o,max:n,step:l,prefix:c,onChange:h}),e.jsx("p",{className:"mt-2.5",style:{fontSize:"13px",color:p,lineHeight:"19px"},children:r})]})}function W({label:t,value:r,accented:s=!1}){return e.jsxs("div",{className:"flex items-baseline justify-between gap-6 py-3",style:{borderTop:`1px solid ${q}`},children:[e.jsx("span",{style:{fontSize:"15px",color:s?u:x,lineHeight:"22px"},children:t}),e.jsx("span",{style:{fontSize:"16px",fontWeight:420,whiteSpace:"nowrap",color:s?R:u},children:r})]})}function ie(){const[t,r]=d.useState(250),[s,o]=d.useState(2),[n,l]=d.useState(700),[c,h]=d.useState(1),a=d.useMemo(()=>re({xamlFiles:t,engineers:s,dayRate:n,suites:c}),[t,s,n,c]),m=J.business,g=a.costLow/m,y=a.costHigh/m;return e.jsxs("div",{className:"grid lg:grid-cols-[minmax(0,1fr)_minmax(0,1.15fr)] gap-6 lg:gap-8 items-start",children:[e.jsxs("div",{className:"rounded-2xl p-8",style:{backgroundColor:"rgba(255,255,255,0.03)",border:M},children:[e.jsx("p",{className:"mb-6",style:{fontSize:"12px",letterSpacing:"var(--letter-spacing-label)",fontWeight:420,color:p},children:"Your application"}),e.jsxs("div",{className:"flex flex-col gap-6",children:[e.jsx(C,{label:"XAML files",hint:e.jsxs(e.Fragment,{children:["Windows, pages, user controls and dictionaries. Count them with"," ",e.jsx("code",{style:{fontFamily:"var(--font-mono)",fontSize:"12px",color:x},children:"find . -name '*.xaml' | wc -l"})]}),value:t,min:1,max:2e4,step:10,onChange:r}),e.jsx(C,{label:"Engineers on the rewrite",hint:"Changes how long it takes, not what it costs. The total effort is the same.",value:s,min:1,max:100,step:1,onChange:o}),e.jsx(C,{label:"Blended day rate",hint:"Fully loaded cost per engineer-day, including employer taxes and overhead.",value:n,min:0,max:5e3,step:50,prefix:"â¬",onChange:l}),e.jsx(C,{label:"Commercial control suites",hint:"DevExpress, Telerik, Infragistics, Syncfusion, Actipro, SciChart and similar.",value:c,min:0,max:20,step:1,onChange:h})]})]}),e.jsxs("div",{className:"rounded-2xl p-8",style:{backgroundColor:"rgba(255,255,255,0.03)",border:M},children:[e.jsx("p",{className:"mb-6",style:{fontSize:"12px",letterSpacing:"var(--letter-spacing-label)",fontWeight:420,color:p},children:"Rewriting it yourself"}),e.jsxs("p",{style:{fontFamily:"var(--font-sans)",fontSize:"clamp(32px, 4.2vw, 46px)",fontWeight:380,lineHeight:1.05,letterSpacing:"var(--letter-spacing-title)",color:u,marginBottom:"8px"},children:[b(a.costLow)," to ",b(a.costHigh)]}),e.jsxs("p",{className:"mb-8",style:{fontSize:"15px",color:p,lineHeight:"23px"},children:["Roughly ",F(a.monthsLow)," to ",F(a.monthsHigh)," months of calendar time with ",s," ",s===1?"engineer":"engineers"," on it, during which that team ships nothing else."]}),e.jsxs("div",{className:"mb-8",children:[e.jsx(W,{label:"Build effort",value:`${Math.round(a.baseDaysLow).toLocaleStr
1ing("en-GB")} to ${Math.round(a.baseDaysHigh).toLocaleString("en-GB")} engineer-days`}),a.hasContingency&&e.jsx(W,{label:`Third-party contingency (${Math.round(A*100)} to ${Math.round(P*100)}%)`,value:`+ ${b(a.contingencyLow)} to ${b(a.contingencyHigh)}`}),e.jsx(W,{label:"Roadmap not shipped",value:`${F(a.monthsLow)} to ${F(a.monthsHigh)} months`}),e.jsx(W,{label:"Avalonia XPF, Business tier",value:b(m),accented:!0})]}),e.jsx("div",{className:"rounded-xl p-6 mb-8",style:{backgroundColor:"rgba(31, 158, 255, 0.07)",border:"1px solid rgba(31, 158, 255, 0.22)"},children:e.jsx("p",{style:{fontSize:"16px",lineHeight:"26px",color:u},children:y<1?e.jsxs(e.Fragment,{children:["A rewrite here costs"," ",e.jsx("strong",{style:{color:R,fontWeight:500},children:"less than the XPF licence"}),". At this size, porting to free Avalonia is probably the better call, and we would rather tell you that than sell you something you do not need."]}):g<1?e.jsxs(e.Fragment,{children:["A rewrite here lands"," ",e.jsx("strong",{style:{color:R,fontWeight:500},children:"in the same range as the XPF licence"}),". This is the size where the answer genuinely depends on your codebase rather than on the arithmetic, and porting to free Avalonia may well be the better call. Worth a conversation before you decide either way."]}):e.jsxs(e.Fragment,{children:["A rewrite costs"," ",e.jsxs("strong",{style:{color:R,fontWeight:500},children:[g.toFixed(1),"x to ",y.toFixed(1),"x the XPF licence"]}),", and at the end of it you have the feature set you already had today."]})})}),e.jsx("p",{style:{fontSize:"14px",color:p,lineHeight:"22px"},children:"XPF needs no contingency buffer for third-party controls, because it does not touch that code. Your existing suites are WPF controls, and XPF runs WPF."})]}),e.jsx("div",{className:"lg:col-span-2",children:e.jsxs("details",{className:"rounded-2xl px-8 py-6",style:{backgroundColor:"rgba(255,255,255,0.02)",border:M},children:[e.jsx("summary",{className:"cursor-pointer",style:{fontSize:"15px",fontWeight:420,color:u},children:"What this calculation assumes, and what it leaves out"}),e.jsxs("div",{className:"mt-5 flex flex-col gap-4",style:{maxWidth:"820px"},children:[e.jsxs("p",{style:{color:x},children:["Effort is estimated at ",I," to ",B," engineer-days per XAML file. The range is wide on purpose: a file may be a twenty-line resource dictionary or a nine-hundred-line screen with a custom control tree behind it, and that spread is the largest single source of uncertainty in any estimate of this kind."]}),e.jsxs("p",{style:{color:x},children:["Where you have told us commercial control suites are present, a ",Math.round(A*100)," to"," ",Math.round(P*100)," per cent contingency buffer is applied. That figure is not ours. It is the buffer recommended by published scoping guidance for migrating WPF to other cross-platform XAML targets, which files commercial control suites under red flags that materially raise an estimate."]}),e.jsxs("p",{style:{color:x},children:["Calendar time assumes ",G," working days per engineer-year and that the work parallelises cleanly across your team. That is generous. Migration work has real serialisation points, and adding engineers to a late rewrite is the textbook case where it does not help."]}),e.jsx("p",{style:{color:x},children:"Not included: QA and regression testing, re-certification or compliance sign-off, retraining, documentation, the cost of defects that reach customers, or the revenue effect of a roadmap that stopped moving. Each of those is real, and each of them pushes the number up rather than down."})]})]})})]})}function le(){const t=d.useRef(null),r=se(),[s,o]=d.useState(!1);d.useEffect(()=>o(!0),[]);const n=l=>({opacity:s?1:0,transform:r?void 0:s?"translateY(0)":"translateY(16px)",transition:`opacity 0.6s ${w} ${l}ms, transform 0.9s ${ee} ${l}ms`});return e.jsxs(K,{heroRef:t,children:[e.jsx("script",{type:"application/ld+json",dangerouslySetInnerHTML:{__html:JSON.stringify(U([{name:"Home",url:"https://avaloniaui.net"},{name:"XPF",url:"https://avaloniaui.net/xpf"},{name:"Rewrite cost",url:"https://avaloniaui.net/xpf/rewrite-cost"}]))}}),e.jsxs("div",{className:"xpf-page",children:[e.jsxs("section",{ref:t,className:"relative overflow-hidden px-6 lg:px-10",style:{backgroundColor:N,paddingTop:"clamp(120px, 14vw, 170px
1)",paddingBottom:"clamp(40px, 6vw, 64px)"},children:[e.jsx("div",{"aria-hidden":!0,className:"absolute inset-0 pointer-events-none",style:{background:` 2 radial-gradient(900px 560px at 12% 4%, rgba(0,125,249,0.38) 0%, transparent 62%), 3 radial-gradient(1000px 620px at 88% 12%, rgba(31,158,255,0.26) 0%, transparent 60%), 4 radial-gradient(820px 460px at 50% 30%, rgba(11,42,84,0.45) 0%, transparent 66%) 5 `}}),e.jsx($,{color:"rgba(31,158,255,0.09)",radius:560,fadeFrom:"65%"}),e.jsx("div",{"aria-hidden":!0,className:"absolute inset-x-0 bottom-0 pointer-events-none",style:{height:"40%",background:`linear-gradient(to bottom, transparent, ${N})`}}),e.jsxs("div",{className:"relative z-10 max-w-[900px] mx-auto flex flex-col items-center text-center",style:{gap:"28px"},children:[e.jsx("div",{className:"inline-flex items-center [&_svg]:h-6 [&_svg]:w-auto",style:{color:u,...n(0)},children:e.jsx(D,{logo:_.Xpf})}),e.jsx("h1",{style:{fontFamily:"var(--font-sans)",fontSize:"clamp(38px, 5.4vw, 68px)",fontWeight:380,lineHeight:1.06,letterSpacing:"var(--letter-spacing-hero)",maxWidth:"18ch",...n(90)},children:e.jsx("span",{className:"hero-gradient-text-on-dark",children:"What would rewriting your WPF app actually cost?"})}),e.jsx("p",{style:{maxWidth:"660px",textWrap:"balance",fontSize:"20px",fontWeight:300,lineHeight:"32px",letterSpacing:"0.4px",color:x,...n(180)},children:"Put in your own numbers. The method and every coefficient are on this page, so you can forward the result to whoever has to approve it and have them argue with the assumptions rather than with you."}),e.jsx("p",{style:{fontSize:"13px",letterSpacing:"var(--letter-spacing-label)",fontWeight:380,color:p,...n(260)},children:"This runs in your browser. Nothing is shared with us."})]})]}),e.jsx("section",{className:Z,style:{backgroundColor:N},children:e.jsx("div",{className:"max-w-[1200px] mx-auto",children:e.jsx(S,{children:e.jsx(ie,{})})})}),e.jsxs("section",{className:"relative overflow-hidden px-6 lg:px-10",style:{backgroundColor:N,paddingTop:"clamp(48px, 6vw, 88px)",paddingBottom:"clamp(80px, 10vw, 128px)"},children:[e.jsx("div",{"aria-hidden":!0,className:"absolute inset-0 pointer-events-none",style:{background:` 6 radial-gradient(ellipse 50% 50% at 50% 50%, rgba(0,125,249,0.10) 0%, transparent 70%), 7 radial-gradient(ellipse 40% 40% at 70% 30%, rgba(31,158,255,0.07) 0%, transparent 70%) 8 `}}),e.jsx($,{color:"rgba(31,158,255,0.09)",radius:520,fadeFrom:"70%"}),e.jsxs("div",{className:"relative z-10 max-w-[1240px] mx-auto text-center",children:[e.jsxs(S,{children:[e.jsx("div",{className:"inline-flex items-center justify-center mb-8 [&_svg]:h-6 [&_svg]:w-auto",style:{color:u},children:e.jsx(D,{logo:_.Xpf})}),e.jsx("h2",{className:"mb-6 mx-auto",style:{fontFamily:"var(--font-sans)",fontSize:"clamp(32px, 4.6vw, 58px)",fontWeight:380,lineHeight:1.1,letterSpacing:"var(--letter-spacing-heading)",maxWidth:"20ch"},children:e.jsx("span",{className:"hero-gradient-text-on-dark",children:"Want the real number instead of the estimate?"})}),e.jsx("p",{className:"mx-auto mb-4",style:{maxWidth:"640px",color:x},children:"Bring the actual codebase. We will scope it with you, tell you what XPF does and does not handle in your specific application, and tell you honestly if porting to free Avalonia is the better answer."}),e.jsx("p",{className:"mx-auto mb-14",style:{maxWidth:"640px",color:p},children:"XPF is a binary-compatible WPF runtime. Your XAML, your code-behind and your commercial control suites come with you, and you change one SDK reference."})]}),e.jsxs(S,{delay:90,children:[e.jsx("p",{className:"mb-9",style:{fontSize:"13px",letterSpacing:"var(--letter-spacing-label)",fontWeight:380,color:p},children:"Already shipping in production at"}),e.jsx(te,{opacity:.55})]}),e.jsx(S,{delay:150,children:e.jsxs("div",{className:"flex flex-col sm:flex-row items-center justify-center mt-14",style:{gap:"16px"},children:[e.jsx(H,{to:Q,variant:"white",size:"lg",children:"Talk to the engineers"}),e.jsx(H,{to:"/xpf",variant:"ghost",size:"lg",children:"See how XPF works"})]})})]})]})]})]})}function je(){return Y({title:"What Does a WPF Rewrite Cost? Calculator | Avalonia XPF",description:"Estimate the real cost of rewriting a WPF application: engineer-days, calendar time, and the third-party control contingency buffer. Every assumption is published, and compared against licensing Avalonia XPF instead.",path:"/xpf/rewrite-cost",twitterLabels:[{label:"Tool",data:"Rewrite cost c
8alculator"},{label:"Alternative",data:"No rewrite with XPF"}]})}const Ne=O(function(){return e.jsx(le,{})});export{Ne as default,je as meta};
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.