<!-- ============================================================
GOTHAM BUILDING — Edmondson Village Pad 1 · Interactive Flipbook
Squarespace Code Block embed (self-contained, no external hosting)
Paste this entire block into a CODE block on a blank page.
Requires Business plan or higher (code blocks with scripts).
============================================================= -->
<script>
(function(){
// Inside the Squarespace editor the site runs in a frame —
// show a placeholder there so the page stays editable.
if (window.self !== window.top) {
var n = document.createElement('div');
n.setAttribute('style','padding:2.5rem 1rem;text-align:center;font-family:Arial,sans-serif;color:#888;border:1px dashed #ccc;');
n.textContent = 'Gotham flipbook — renders on the live page. (Hidden in the editor so this page stays editable.)';
if (document.currentScript && document.currentScript.parentNode) {
document.currentScript.parentNode.insertBefore(n, document.currentScript);
}
return;
}
var html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gotham Building — Edmondson Village Pad 1 · PM Proposal</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,400;0,500;0,600;0,700;1,400;1,600;1,700&display=swap" rel="stylesheet">
<style>
:root{
--ink:#0D0D0D; --paper:#FFFFFF; --panel:#F2F2F2; --hair:#D9D9D9;
--grey:#737373; --grey-dk:#404040;
--fs:10.4px;
}
*{box-sizing:border-box; margin:0; padding:0;}
html,body{height:100%;}
body{
font-family:'Montserrat','Helvetica Neue',Arial,sans-serif;
background:var(--ink); color:var(--ink);
display:flex; flex-direction:column; align-items:center; justify-content:center;
overflow:hidden; min-height:100vh; min-height:100dvh;
background-image:radial-gradient(ellipse 90% 70% at 50% 38%, #1c1c1c 0%, #0D0D0D 70%);
}
.stage{flex:1; width:100%; display:flex; align-items:center; justify-content:center; position:relative;}
.bookframe{position:relative;}
.ground{
position:absolute; left:4%; right:4%; bottom:-30px; height:40px;
background:radial-gradient(ellipse 50% 100% at 50% 0%, rgba(0,0,0,.6), rgba(0,0,0,.25) 55%, transparent 78%);
filter:blur(7px); pointer-events:none;
}
/* StPageFlip structural helpers */
.stf__parent{position:relative; display:block;}
.stf__wrapper{position:relative; height:100%;}
.stf__block{position:absolute; width:100%; height:100%;}
#flip.clip .stf__block{overflow:hidden;} /* edge-leak clip, released during turns */
.stf__item{display:none; position:absolute; transform-style:preserve-3d;}
.stf__outerShadow,.stf__innerShadow,.stf__hardShadow,.stf__hardInnerShadow{position:absolute; left:0; top:0;}
.sheetpage{background:var(--paper);}
.sheetpage .page{width:100%; height:100%;}
/* spine gutter shading */
.sheetpage.pg-right .page::after,
.sheetpage.pg-left .page::after{
content:''; position:absolute; top:0; bottom:0; width:10%;
pointer-events:none; z-index:6;
}
.sheetpage.pg-right .page::after{left:0;
background:linear-gradient(90deg, rgba(13,13,13,.18), rgba(13,13,13,.04) 55%, rgba(13,13,13,0));}
.sheetpage.pg-left .page::after{right:0;
background:linear-gradient(270deg, rgba(13,13,13,.18), rgba(13,13,13,.04) 55%, rgba(13,13,13,0));}
/* ---------- page anatomy ---------- */
.page{font-size:var(--fs); display:flex; flex-direction:column; background:var(--paper); position:relative; overflow:hidden;}
.pg-head{
display:flex; justify-content:space-between; align-items:baseline;
padding:2.1em 0 .7em; border-bottom:1px solid var(--hair);
margin:0 2.6em; flex:0 0 auto;
}
.pg-head .wm{font-weight:700; font-size:.72em; letter-spacing:.32em; color:var(--ink);}
.pg-head .pj{font-weight:600; font-size:.66em; letter-spacing:.22em; color:var(--grey);}
.pg-body{flex:1 1 auto; padding:1.4em 2.6em .9em; overflow-y:auto; scrollbar-width:none;}
.pg-body::-webkit-scrollbar{display:none;}
.pg-foot{
flex:0 0 auto; display:flex; justify-content:space-between; align-items:baseline;
margin:0 2.6em; padding:.65em 0 1.7em; border-top:1px solid var(--hair);
}
.pg-foot .tag{font-style:italic; font-weight:600; font-size:.66em; color:var(--grey);}
.pg-foot .no{font-weight:600; font-size:.66em; letter-spacing:.18em; color:var(--grey);}
.pg-foot .no b{color:var(--ink); font-weight:600;}
h1{font-size:1.72em; font-weight:600; font-style:italic; line-height:1.18;
padding-bottom:.42em; border-bottom:1px solid var(--hair); margin-bottom:.85em;}
h2{font-size:.92em; font-weight:600; letter-spacing:.16em; text-transform:uppercase; margin:1.25em 0 .35em;}
h2:first-of-type{margin-top:.2em;}
p{line-height:1.6; margin-bottom:.85em;}
.muted{color:var(--grey);} .small{font-size:.82em;}
em.note{display:block; font-size:.78em; color:var(--grey); margin:.5em 0 .9em;}
.callout{
background:var(--ink); color:#fff; text-align:center;
font-weight:600; font-style:italic; font-size:1.02em; line-height:1.5;
padding:1.15em 1.6em; margin:.4em 0 1.1em;
}
.callout.caps{font-style:normal; font-size:.8em; letter-spacing:.18em; text-transform:uppercase; line-height:1.9;}
.deliv{background:var(--panel); border-left:4px solid var(--ink); padding:.95em 1.3em; margin:.9em 0 .4em;}
.deliv .lbl{font-size:.68em; font-weight:600; letter-spacing:.28em; color:var(--grey-dk); margin-bottom:.5em;}
.deliv .items{font-size:.88em; line-height:1.75;}
.deliv .items i{font-style:normal; color:var(--hair); padding:0 .45em;}
table{width:100%; border-collapse:collapse; margin:.4em 0 .8em;}
th{background:var(--ink); color:#fff; text-align:left; font-size:.68em; font-weight:600;
letter-spacing:.14em; text-transform:uppercase; padding:.85em .9em;}
td{font-size:.85em; line-height:1.45; padding:.75em .9em; border-bottom:1px solid var(--hair); vertical-align:top;}
tr.band td{background:var(--panel); font-weight:600;}
.num{text-align:right; white-space:nowrap;} th.num{text-align:right;}
td.wk,th.wk{white-space:nowrap; font-weight:600; letter-spacing:.1em;}
.pri{font-size:.78em; font-weight:600; letter-spacing:.08em; white-space:nowrap;}
.pri.c{color:var(--ink);} .pri.h{color:var(--grey-dk);} .pri.m{color:var(--grey);}
td .iss{font-weight:600;}
ul.gb{list-style:none; margin:.2em 0 .8em;}
ul.gb li{position:relative; padding-left:1.5em; line-height:1.55; margin-bottom:.55em;}
ul.gb li::before{content:'▪'; position:absolute; left:.1em; color:var(--ink);}
.report li b{letter-spacing:.1em; font-weight:600;}
.report li span.dash{color:var(--grey); padding:0 .3em;}
.sigs{display:flex; gap:2.4em; margin-top:1.6em;}
.sig{flex:1;}
.sig .party{font-size:.74em; font-weight:600; letter-spacing:.18em; line-height:1.5; margin-bottom:1.4em;}
.sig .line{border-bottom:1.5px solid var(--ink); height:2.4em;}
.sig .lab{font-size:.6em; font-weight:600; letter-spacing:.24em; color:var(--grey); margin:.4em 0 1.2em;}
.page.cover{padding:2.4em 2.6em;}
.cover .band{background:var(--ink); color:#fff; padding:1.9em 2em; margin-bottom:3.4em;}
.cover .band .l1{font-weight:700; font-size:1.34em; letter-spacing:.5em;}
.cover .band .l2{font-weight:600; font-size:.64em; letter-spacing:.42em; margin-top:.55em; opacity:.92;}
.cover .eyebrow{font-weight:600; font-size:.78em; letter-spacing:.3em; color:var(--grey); line-height:1.9; margin-bottom:1.3em;}
.cover .title{font-weight:700; font-size:3.05em; line-height:1.08;}
.cover .title i{font-weight:600; color:var(--grey);}
.cover .loc{font-size:1.02em; color:var(--grey-dk); margin-top:.8em;}
.cover .meta{border-top:1px solid var(--hair); margin-top:2.6em; padding-top:1.3em;}
.cover .meta .lab{font-size:.64em; font-weight:600; letter-spacing:.26em; color:var(--grey); margin-bottom:.25em;}
.cover .meta .val{font-size:.98em; margin-bottom:1.1em;}
.cover .foot{margin-top:auto; border-top:2.5px solid var(--ink); padding-top:.9em;}
.cover .foot .tg{font-weight:600; font-style:italic; font-size:1em;}
.cover .foot .co{font-size:.6em; letter-spacing:.26em; color:var(--grey); margin-top:.45em;}
.controls{
flex:0 0 auto; width:100%;
display:flex; align-items:center; justify-content:center;
padding:1.05rem .2rem 1.25rem; color:#fff; user-select:none;
}
.ctr{display:flex; flex-direction:column; align-items:center; gap:.28rem;}
.sect{font-weight:600; font-size:.68rem; letter-spacing:.3em; text-transform:uppercase; color:#fff;}
.count{font-size:.62rem; letter-spacing:.2em; color:#8a8a8a;}
.side{
position:absolute; top:50%; transform:translateY(-50%);
background:none; border:0; color:#fff; cursor:pointer; z-index:50;
font-size:2rem; line-height:1; padding:1.2rem .9rem; opacity:.75;
transition:opacity .25s;
font-family:'Montserrat',sans-serif; font-weight:400;
}
.side:hover:not(:disabled){opacity:1;}
.side:focus-visible{outline:2px solid #fff; outline-offset:2px;}
.side:disabled{opacity:.12; cursor:default;}
.side.l{left:8px;} .side.r{right:8px;}
.progress{position:fixed; left:0; bottom:0; height:3px; background:#fff; width:0; transition:width .6s ease;}
@media (max-width:520px){
.side{font-size:1.55rem; padding:.9rem .45rem;}
.side.l{left:0;} .side.r{right:0;}
}
</style>
</head>
<body>
<div class="stage">
<button class="side l" id="prev" aria-label="Previous page">‹</button>
<div class="bookframe" id="frame">
<div class="ground"></div>
<div id="flip">
<section class="page cover" data-title="Cover">
<div class="band"><div class="l1">GOTHAM BUILDING</div><div class="l2">PROJECT MANAGEMENT SERVICES</div></div>
<div class="eyebrow">OWNER’S PRECONSTRUCTION & CONSTRUCTION<br>PROJECT MANAGEMENT PROPOSAL</div>
<div class="title">EDMONDSON<br>VILLAGE <i>— PAD 1</i></div>
<div class="loc">Baltimore, Maryland</div>
<div class="meta">
<div class="lab">PREPARED FOR</div><div class="val">[Client Name]</div>
<div class="lab">DATE</div><div class="val">[Date]</div>
</div>
<div class="foot"><div class="tg">Save Money. Save Time. Stay in Control.</div>
<div class="co">GOTHAM BUILDING PROJECT MANAGEMENT SERVICES</div></div>
</section>
<section class="page" data-title="Executive Summary">
<div class="pg-body">
<div class="callout">Resolve ambiguity while it is still a question — before it becomes a change order or delay.</div>
<h1>Executive Summary</h1>
<p>Gotham Building Project Management Services has completed an initial review of the available Edmondson Village Pad 1 bid, permit, specification, structural, MEP, sustainability, and related project documents. The project design intent is generally understandable and the project can move forward. The current bid package, however, contains coordination issues, scope ambiguities, and commercial inconsistencies that should be resolved before final pricing and contract award.</p>
<p>The principal Owner risk is not any single drafting error. It is that bidders may interpret unresolved requirements differently. That can produce bids that appear comparable but carry materially different scopes, followed by exclusions, change orders, procurement impacts, or schedule disputes after award.</p>
<p>Gotham proposes to provide the Owner with an independent project-control function through preconstruction, procurement, construction, and closeout. The objective is to establish one documented bid basis, assign responsibilities, normalize bids, preserve the project record, independently test changes and delays, and drive unresolved issues to timely decisions.</p>
</div>
</section>
<section class="page" data-title="Why This Matters">
<div class="pg-body">
<h1>Why This Matters</h1>
<table>
<tr><th>Ambiguous Document</th><th>Bidder Assumption</th><th>Contract Scope Gap</th><th>Change / Delay</th></tr>
<tr><td>Unresolved requirement</td><td>Different pricing basis</td><td>Exclusion survives award</td><td>Owner exposure increases</td></tr>
</table>
<p style="text-align:center; font-weight:600; font-style:italic; margin:.6em 0 1.4em;">Gotham’s objective is to interrupt this sequence before contract award.</p>
<h1>Gotham’s Role</h1>
<p>The Architect remains responsible for design and interpretation of the Contract Documents. The Contractor remains responsible for construction, means and methods, sequencing, coordination, safety, subcontractor management, and contractual performance. Gotham represents the Owner by managing the space between those responsibilities: scope, decisions, cost, schedule, documentation, accountability, and unresolved risk.</p>
<div class="callout">The GC manages construction. Gotham manages the Owner’s exposure to construction.</div>
</div>
</section>
<section class="page" data-title="Phase I — Preconstruction">
<div class="pg-body">
<h1>Phase I — Preconstruction & Bid Package Coordination</h1>
<h2>Document Control & Risk Review</h2>
<p>Establish the current project record and maintain a consolidated Preconstruction Risk & Clarification Log identifying document conflicts, missing information, scope ambiguities, trade interfaces, shell/tenant boundaries, delegated design, testing, procurement, and schedule exposure.</p>
<h2>Design Clarification / RFI Management</h2>
<p>Consolidate bid-critical questions and coordinate written resolution with the Architect, engineers, Owner, and responsible consultants so all bidders price the same answer.</p>
<h2>Scope Responsibility Matrix</h2>
<p>Define Furnish, Install, Coordinate, Engineer, Permit, Test/Inspect, Protect, and Warranty responsibility for major systems and interfaces.</p>
<h2>Bid Package Coordination</h2>
<p>Carry material clarifications into addenda, scope sheets, bidder instructions, and contract exhibits so known ambiguities do not survive award.</p>
<div class="deliv"><div class="lbl">KEY DELIVERABLES</div>
<div class="items">Project Document Register<i>·</i>Preconstruction Risk & Clarification Log<i>·</i>Consolidated Bid RFI Log<i>·</i>Scope Responsibility Matrix<i>·</i>Bidder Scope/Qualification Form<i>·</i>Bid Milestone & Procurement Schedule<i>·</i>Recommended Addendum Items</div>
</div>
</div>
</section>
<section class="page" data-title="Phase II — Bidding & Award">
<div class="pg-body">
<h1>Phase II — Bidding, Leveling & Award</h1>
<p>Gotham will evaluate the complete bid basis, not simply the bottom-line number. Proposals will be reviewed for inclusions, exclusions, qualifications, allowances, alternates, substitutions, unit prices, schedule assumptions, long-lead items, bonding/insurance, delegated design, testing, permits, and closeout.</p>
<table>
<tr><th>Illustrative Bid Leveling</th><th class="num">Bidder A</th><th class="num">Bidder B</th><th class="num">Bidder C</th></tr>
<tr><td>Submitted Bid</td><td class="num">$1.000M</td><td class="num">$0.940M</td><td class="num">$0.975M</td></tr>
<tr><td>Missing / Excluded Scope</td><td class="num">$0.020M</td><td class="num">$0.105M</td><td class="num">$0.035M</td></tr>
<tr class="band"><td>Normalized Cost</td><td class="num">$1.020M</td><td class="num">$1.045M</td><td class="num">$1.010M</td></tr>
</table>
<em class="note">Illustrative only. The lowest submitted bid is not necessarily the lowest complete project cost.</em>
<div class="deliv"><div class="lbl">KEY DELIVERABLES</div>
<div class="items">Bid Comparison<i>·</i>Qualification Matrix<i>·</i>Normalized Bid Analysis<i>·</i>Scope Review Minutes<i>·</i>Procurement/Long-Lead Assessment<i>·</i>Award Recommendation<i>·</i>Final Scope Clarification Exhibit</div>
</div>
</div>
</section>
<section class="page" data-title="Phase III — Construction PM">
<div class="pg-body">
<h1>Phase III — Construction Project Management</h1>
<h2>Cost Control</h2>
<p>Maintain Owner cost reporting and independently evaluate proposed changes against original scope, authorization, notice, quantities, labor/material support, markup, and schedule effect.</p>
<h2>Schedule Control</h2>
<p>Review baseline and updates against Owner milestones; track design decisions, submittals, procurement, utilities, inspections, commissioning, and turnover. Delay assertions are tested against actual activities, dates, critical-path effect, concurrency, and mitigation.</p>
<h2>Project Administration</h2>
<p>Manage or monitor Owner/Architect/Contractor meetings, action logs, RFIs, submittals, decisions, procurement, payment applications, testing, inspections, deficiencies, and unresolved issues.</p>
<h2>Quality & Envelope Control</h2>
<p>Coordinate preinstallation meetings, mockups, WRB transitions, flashing, storefront interfaces, roof/wall transitions, penetrations, sealants, canopy attachments, manufacturer requirements, and required inspections before concealment.</p>
<h2>IGCC, Commissioning & Closeout</h2>
<p>Establish responsibility and due dates for IGCC records, commissioning/FPT, waste-management documentation, inspections, test reports, warranties, O&M information, record documents, punch list, and permit/AHJ closeout.</p>
</div>
</section>
<section class="page" data-title="Owner Reporting">
<div class="pg-body">
<h1>Owner Reporting</h1>
<p>Gotham will provide concise executive reporting centered on decisions and exposure:</p>
<ul class="gb report">
<li><b>COST</b><span class="dash">—</span>Budget, commitments, pending changes, forecast exposure, and forecast final cost.</li>
<li><b>SCHEDULE</b><span class="dash">—</span>Current status, milestone variance, critical risks, and recovery actions.</li>
<li><b>PROCUREMENT</b><span class="dash">—</span>Long-lead status and decisions required.</li>
<li><b>DECISIONS</b><span class="dash">—</span>Owner/design decisions, responsible party, required date, and consequence of delay.</li>
<li><b>CHANGES</b><span class="dash">—</span>Approved, pending, disputed, and forecast changes.</li>
<li><b>QUALITY</b><span class="dash">—</span>Inspections, deficiencies, envelope issues, and close-in hold points.</li>
<li><b>RISK</b><span class="dash">—</span>Items capable of materially affecting cost, completion, or turnover.</li>
</ul>
</div>
</section>
<section class="page" data-title="30-Day Action Plan">
<div class="pg-body">
<h1>Immediate 30-Day Action Plan</h1>
<table>
<tr><th class="wk">Week</th><th>Focus</th><th>Actions</th></tr>
<tr><td class="wk">WEEK 1</td><td><b>Establish the Record</b></td><td>Confirm current documents/addenda; establish document register; open risk and decision logs.</td></tr>
<tr><td class="wk">WEEK 2</td><td><b>Resolve Bid-Critical Questions</b></td><td>Consolidate and drive clarification of shell/tenant scope, assemblies, hardware, envelope interfaces, interiors, and commercial-document issues.</td></tr>
<tr><td class="wk">WEEK 3</td><td><b>Establish Common Bid Basis</b></td><td>Finalize responsibility matrix, bidder scope sheets, milestone schedule, procurement requirements, and addendum items.</td></tr>
<tr><td class="wk">WEEK 4</td><td><b>Bid & Award Control</b></td><td>Normalize bids, identify exclusions, conduct scope reviews, and prepare the Owner’s award recommendation.</td></tr>
</table>
</div>
</section>
<section class="page" data-title="Commercial Logic">
<div class="pg-body">
<h1>Commercial Logic for the Owner</h1>
<p>Before award, an ambiguity is a question. After award, the same ambiguity can become a change order. After procurement or installation begins, it can become a change order plus schedule impact. Gotham’s initial priority is therefore to move project risk upstream, where it is less expensive to resolve.</p>
<div class="callout caps">One Set of Documents | One Understood Scope | One Bid Basis | One Responsibility Structure | One Documented Record</div>
</div>
</section>
<section class="page" data-title="Fee Structure">
<div class="pg-body">
<h1>Proposed Fee Structure</h1>
<table>
<tr><th>Service</th><th>Basis</th><th class="num">Fee</th></tr>
<tr><td>Phase I — Preconstruction / Bid Package Coordination</td><td>Fixed Fee</td><td class="num">$________</td></tr>
<tr><td>Phase II — Bid Leveling / Procurement / Award</td><td>Fixed Fee</td><td class="num">$________</td></tr>
<tr><td>Phase III — Construction Project Management</td><td>Monthly; anticipated ____ months</td><td class="num">$________ / month</td></tr>
</table>
<p class="small"><b>Additional Services:</b> only upon written Owner authorization, at agreed hourly rates or a negotiated lump sum.</p>
<h1 style="margin-top:1.2em;">Assumptions & Limits</h1>
<ul class="gb small">
<li>Gotham’s services are project management and owner’s representation; they do not replace architectural, engineering, legal, safety, or contractor responsibilities.</li>
<li>Design interpretations and revisions remain the responsibility of the design professionals of record.</li>
<li>Contractor means, methods, sequencing, site safety, subcontractor performance, and construction execution remain the Contractor’s responsibility.</li>
<li>Legal conclusions regarding breach, default, negligence, waiver, or other legal rights are outside this proposal and should be reviewed by Owner’s counsel when required.</li>
<li>Final scope, schedule, staffing level, meeting cadence, and fee will be confirmed with the Owner before execution.</li>
</ul>
</div>
</section>
<section class="page" data-title="Authorization">
<div class="pg-body">
<h1>Authorization</h1>
<p>Gotham’s objective is to identify material issues early, establish responsibility, document decisions, understand cost and schedule consequences, and drive unresolved matters to closure.</p>
<div class="sigs">
<div class="sig">
<div class="party">ACCEPTED FOR<br>[CLIENT NAME]</div>
<div class="line"></div><div class="lab">SIGNATURE</div>
<div class="line"></div><div class="lab">NAME / TITLE</div>
<div class="line"></div><div class="lab">DATE</div>
</div>
<div class="sig">
<div class="party">GOTHAM BUILDING<br>PROJECT MANAGEMENT SERVICES</div>
<div class="line"></div><div class="lab">SIGNATURE</div>
<div class="line"></div><div class="lab">NAME / TITLE</div>
<div class="line"></div><div class="lab">DATE</div>
</div>
</div>
</div>
</section>
<section class="page" data-title="Appendix A — Risk Register">
<div class="pg-body">
<h1>Appendix A — Preliminary Risk Register</h1>
<p class="small">This appendix summarizes selected items identified during Gotham’s preliminary review. It is not a substitute for the complete coordinated document review proposed in Phase I.</p>
<table>
<tr><th>Priority</th><th>Issue</th><th>Current Concern</th><th>Owner</th><th>Required Action</th></tr>
<tr><td class="pri c">CRITICAL</td><td class="iss">Project address</td><td>4404 vs. 4522 Edmondson Avenue references</td><td>Architect / Owner</td><td>Confirm and reissue affected documents</td></tr>
<tr><td class="pri c">CRITICAL</td><td class="iss">Contract / bid information</td><td>Obsolete dates and incomplete/inconsistent commercial documents</td><td>Owner / GC / Architect</td><td>Issue current bid milestones and complete contract basis</td></tr>
<tr><td class="pri c">CRITICAL</td><td class="iss">Shell / tenant interface</td><td>Slab identified as tenant work while under-slab insulation/vapor-retarder requirements appear in specifications</td><td>Architect / Owner</td><td>Define responsibility and sequencing</td></tr>
<tr><td class="pri c">CRITICAL</td><td class="iss">Exterior sheathing</td><td>OSB/plywood vs. exterior gypsum requirements</td><td>Architect / Structural</td><td>Confirm intended wall assembly</td></tr>
<tr><td class="pri h">HIGH</td><td class="iss">Door hardware</td><td>Residential template content does not align with shell project</td><td>Architect</td><td>Issue project-specific D1/D2 hardware sets</td></tr>
</table>
</div>
</section>
<section class="page" data-title="Appendix A — Risk Register">
<div class="pg-body">
<h1 style="font-size:1.1em;">Appendix A — Preliminary Risk Register <span class="muted">(continued)</span></h1>
<table>
<tr><th>Priority</th><th>Issue</th><th>Current Concern</th><th>Owner</th><th>Required Action</th></tr>
<tr><td class="pri h">HIGH</td><td class="iss">Interior scope</td><td>Drywall, paint, base and signage applicability is unclear against tenant-fit-out limits</td><td>Architect / Owner</td><td>Issue shell finish schedule</td></tr>
<tr><td class="pri h">HIGH</td><td class="iss">Envelope interfaces</td><td>Multiple trades share WRB, masonry, rainscreen, storefront, flashing, sealants and roofing interfaces</td><td>GC / Architect</td><td>Issue responsibility matrix and coordinate details</td></tr>
<tr><td class="pri h">HIGH</td><td class="iss">Canopy</td><td>Delegated-design, attachment, flashing and structural coordination require definition</td><td>Architect / Structural / Supplier</td><td>Confirm criteria and responsibility</td></tr>
<tr><td class="pri h">HIGH</td><td class="iss">MEP document status</td><td>Some permit MEP information is marked Not for Construction</td><td>Design Team / Owner</td><td>Define bid/IFC status and change treatment</td></tr>
<tr><td class="pri m">MEDIUM</td><td class="iss">IGCC / commissioning</td><td>Requirements exist but execution, documentation and trade allocation require active management</td><td>GC / Gotham</td><td>Establish compliance/closeout matrix</td></tr>
</table>
</div>
</section>
<section class="page" data-title="Appendix B — Transmittal Email">
<div class="pg-body">
<h1>Appendix B — Client Transmittal Email</h1>
<p class="small"><b>Subject:</b> Edmondson Village Pad 1 — Preconstruction Review & Recommended Owner PM Support</p>
<p class="small">Hi [Client Name],</p>
<p class="small">We completed an initial review of the Edmondson Village Pad 1 bid and permit documents. The project itself is straightforward and the overall design intent is understandable. However, the current bid package contains several coordination and scope issues that should be resolved before final pricing and contract award.</p>
<p class="small">The concern is less about individual drafting errors and more about their commercial effect. The current record includes inconsistencies involving project identification, shell-versus-tenant scope, building-envelope assemblies and trade interfaces, door/hardware requirements, interior finish scope, contract requirements, and bid/schedule information.</p>
<p class="small">None of these issues is unusual or necessarily expensive to correct during preconstruction. The risk comes from allowing bidders to resolve them through their own assumptions. That can result in bids that appear competitive but contain materially different scopes, followed by exclusions, change orders, or schedule impacts after award.</p>
<p class="small">Gotham can provide value by establishing a single, documented bid basis before the Owner commits construction dollars. Our recommended approach is to complete the document review, consolidate bid-critical RFIs, establish a scope-responsibility matrix, coordinate responses with the design team, level contractor proposals, and carry the resulting clarifications into the final contract scope.</p>
<p class="small">If retained through construction, Gotham would continue as the Owner’s project-management representative, independently monitoring cost, schedule, procurement, RFIs/submittals, change orders, payment applications, quality-control milestones, IGCC/commissioning requirements, and closeout.</p>
<p class="small">The attached proposal outlines our recommended approach. The objective is simple: resolve ambiguity while it is still a question, rather than after it becomes a change order or delay.</p>
<p class="small">Best,<br>[Name]<br><b>Gotham Building Project Management Services</b><br><span class="muted">[Phone] | [Email]</span></p>
</div>
</section>
</div>
</div>
<button class="side r" id="next" aria-label="Next page">›</button>
</div>
<div class="controls">
<div class="ctr">
<div class="sect" id="sect">Cover</div>
<div class="count" id="count"></div>
</div>
</div>
<div class="progress" id="prog"></div>
<script>
/*!
* page-flip (StPageFlip) v2.x — https://github.com/Nodlik/StPageFlip
* MIT License — Copyright (c) 2020 Nodlik
* Bundled inline for a self-contained flipbook. Full license text:
* https://github.com/Nodlik/StPageFlip/blob/master/LICENSE
*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).St={})}(this,(function(t){"use strict";class e{constructor(t,e){this.state={angle:0,area:[],position:{x:0,y:0},hardAngle:0,hardDrawingAngle:0},this.createdDensity=e,this.nowDrawingDensity=this.createdDensity,this.render=t}setDensity(t){this.createdDensity=t,this.nowDrawingDensity=t}setDrawingDensity(t){this.nowDrawingDensity=t}setPosition(t){this.state.position=t}setAngle(t){this.state.angle=t}setArea(t){this.state.area=t}setHardDrawingAngle(t){this.state.hardDrawingAngle=t}setHardAngle(t){this.state.hardAngle=t,this.state.hardDrawingAngle=t}setOrientation(t){this.orientation=t}getDrawingDensity(){return this.nowDrawingDensity}getDensity(){return this.createdDensity}getHardAngle(){return this.state.hardAngle}}class i extends e{constructor(t,e,i){super(t,i),this.image=null,this.isLoad=!1,this.loadingAngle=0,this.image=new Image,this.image.src=e}draw(t){const e=this.render.getContext(),i=this.render.convertToGlobal(this.state.position),s=this.render.getRect().pageWidth,n=this.render.getRect().height;e.save(),e.translate(i.x,i.y),e.beginPath();for(let t of this.state.area)null!==t&&(t=this.render.convertToGlobal(t),e.lineTo(t.x-i.x,t.y-i.y));e.rotate(this.state.angle),e.clip(),this.isLoad?e.drawImage(this.image,0,0,s,n):this.drawLoader(e,{x:0,y:0},s,n),e.restore()}simpleDraw(t){const e=this.render.getRect(),i=this.render.getContext(),s=e.pageWidth,n=e.height,h=1===t?e.left+e.pageWidth:e.left,r=e.top;this.isLoad?i.drawImage(this.image,h,r,s,n):this.drawLoader(i,{x:h,y:r},s,n)}drawLoader(t,e,i,s){t.beginPath(),t.strokeStyle="rgb(200, 200, 200)",t.fillStyle="rgb(255, 255, 255)",t.lineWidth=1,t.rect(e.x+1,e.y+1,i-1,s-1),t.stroke(),t.fill();const n={x:e.x+i/2,y:e.y+s/2};t.beginPath(),t.lineWidth=10,t.arc(n.x,n.y,20,this.loadingAngle,3*Math.PI/2+this.loadingAngle),t.stroke(),t.closePath(),this.loadingAngle+=.07,this.loadingAngle>=2*Math.PI&&(this.loadingAngle=0)}load(){this.isLoad||(this.image.onload=()=>{this.isLoad=!0})}newTemporaryCopy(){return this}getTemporaryCopy(){return this}hideTemporaryCopy(){}}class s{constructor(t,e){this.pages=[],this.currentPageIndex=0,this.currentSpreadIndex=0,this.landscapeSpread=[],this.portraitSpread=[],this.render=e,this.app=t,this.currentPageIndex=0,this.isShowCover=this.app.getSettings().showCover}destroy(){this.pages=[]}createSpread(){this.landscapeSpread=[],this.portraitSpread=[];for(let t=0;t<this.pages.length;t++)this.portraitSpread.push([t]);let t=0;this.isShowCover&&(this.pages[0].setDensity("hard"),this.landscapeSpread.push([t]),t++);for(let e=t;e<this.pages.length;e+=2)e<this.pages.length-1?this.landscapeSpread.push([e,e+1]):(this.landscapeSpread.push([e]),this.pages[e].setDensity("hard"))}getSpread(){return"landscape"===this.render.getOrientation()?this.landscapeSpread:this.portraitSpread}getSpreadIndexByPage(t){const e=this.getSpread();for(let i=0;i<e.length;i++)if(t===e[i][0]||t===e[i][1])return i;return null}getPageCount(){return this.pages.length}getPages(){return this.pages}getPage(t){if(t>=0&&t<this.pages.length)return this.pages[t];throw new Error("Invalid page number")}nextBy(t){const e=this.pages.indexOf(t);return e<this.pages.length-1?this.pages[e+1]:null}prevBy(t){const e=this.pages.indexOf(t);return e>0?this.pages[e-1]:null}getFlippingPage(t){const e=this.currentSpreadIndex;if("portrait"===this.render.getOrientation())return 0===t?this.pages[e].newTemporaryCopy():this.pages[e-1];{const i=0===t?this.getSpread()[e+1]:this.getSpread()[e-1];return 1===i.length||0===t?this.pages[i[0]]:this.pages[i[1]]}}getBottomPage(t){const e=this.currentSpreadIndex;if("portrait"===this.render.getOrientation())return 0===t?this.pages[e+1]:this.pages[e-1];{const i=0===t?this.getSpread()[e+1]:this.getSpread()[e-1];return 1===i.length?this.pages[i[0]]:0===t?this.pages[i[1]]:this.pages[i[0]]}}showNext(){this.currentSpreadIndex<this.getSpread().length&&(this.currentSpreadIndex++,this.showSpread())}showPrev(){this.currentSpreadIndex>0&&(this.currentSpreadIndex--,this.showSpread())}getCurrentPageIndex(){return this.currentPageIndex}show(t=null){if(null===t&&(t=this.currentPageIndex),t<0||t>=this.pages.length)return;const e=this.getSpreadIndexByPage(t);null!==e&&(this.currentSpreadIndex=e,this.showSpread())}getCurrentSpreadIndex(){return this.currentSpreadIndex}setCurrentSpreadIndex(t){if(!(t>=0&&t<this.getSpread().length))throw new Error("Invalid page");this.currentSpreadIndex=t}showSpread(){const t=this.getSpread()[this.currentSpreadIndex];2===t.length?(this.render.setLeftPage(this.pages[t[0]]),this.render.setRightPage(this.pages[t[1]])):"landscape"===this.render.getOrientation()&&t[0]===this.pages.length-1?(this.render.setLeftPage(this.pages[t[0]]),this.render.setRightPage(null)):(this.render.setLeftPage(null),this.render.setRightPage(this.pages[t[0]])),this.currentPageIndex=t[0],this.app.updatePageIndex(this.currentPageIndex)}}class n extends s{constructor(t,e,i){super(t,e),this.imagesHref=i}load(){for(const t of this.imagesHref){const e=new i(this.render,t,"soft");e.load(),this.pages.push(e)}this.createSpread()}}class h{static GetDistanceBetweenTwoPoint(t,e){return null===t||null===e?1/0:Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}static GetSegmentLength(t){return h.GetDistanceBetweenTwoPoint(t[0],t[1])}static GetAngleBetweenTwoLine(t,e){const i=t[0].y-t[1].y,s=e[0].y-e[1].y,n=t[1].x-t[0].x,h=e[1].x-e[0].x;return Math.acos((i*s+n*h)/(Math.sqrt(i*i+n*n)*Math.sqrt(s*s+h*h)))}static PointInRect(t,e){return null===e?null:e.x>=t.left&&e.x<=t.width+t.left&&e.y>=t.top&&e.y<=t.top+t.height?e:null}static GetRotatedPoint(t,e,i){return{x:t.x*Math.cos(i)+t.y*Math.sin(i)+e.x,y:t.y*Math.cos(i)-t.x*Math.sin(i)+e.y}}static LimitPointToCircle(t,e,i){if(h.GetDistanceBetweenTwoPoint(t,i)<=e)return i;const s=t.x,n=t.y,r=i.x,o=i.y;let a=Math.sqrt(Math.pow(e,2)*Math.pow(s-r,2)/(Math.pow(s-r,2)+Math.pow(n-o,2)))+s;i.x<0&&(a*=-1);let g=(a-s)*(n-o)/(s-r)+n;return s-r+n===0&&(g=e),{x:a,y:g}}static GetIntersectBetweenTwoSegment(t,e,i){return h.PointInRect(t,h.GetIntersectBeetwenTwoLine(e,i))}static GetIntersectBeetwenTwoLine(t,e){const i=t[0].y-t[1].y,s=e[0].y-e[1].y,n=t[1].x-t[0].x,h=e[1].x-e[0].x,r=t[0].x*t[1].y-t[1].x*t[0].y,o=e[0].x*e[1].y-e[1].x*e[0].y,a=i*o-s*r,g=n*o-h*r,l=-(r*h-o*n)/(i*h-s*n),d=-(i*o-s*r)/(i*h-s*n);if(isFinite(l)&&isFinite(d))return{x:l,y:d};if(Math.abs(a-g)<.1)throw new Error("Segment included");return null}static GetCordsFromTwoPoint(t,e){const i=Math.abs(t.x-e.x),s=Math.abs(t.y-e.y),n=Math.max(i,s),h=[t];function r(t,e,i,s,n){return e>t?t+n*(i/s):e<t?t-n*(i/s):t}for(let o=1;o<=n;o+=1)h.push({x:r(t.x,e.x,i,n,o),y:r(t.y,e.y,s,n,o)});return h}}class r extends e{constructor(t,e,i){super(t,i),this.copiedElement=null,this.temporaryCopy=null,this.isLoad=!1,this.element=e,this.element.classList.add("stf__item"),this.element.classList.add("--"+i)}newTemporaryCopy(){return"hard"===this.nowDrawingDensity?this:(null===this.temporaryCopy&&(this.copiedElement=this.element.cloneNode(!0),this.element.parentElement.appendChild(this.copiedElement),this.temporaryCopy=new r(this.render,this.copiedElement,this.nowDrawingDensity)),this.getTemporaryCopy())}getTemporaryCopy(){return this.temporaryCopy}hideTemporaryCopy(){null!==this.temporaryCopy&&(this.copiedElement.remove(),this.copiedElement=null,this.temporaryCopy=null)}draw(t){const e=t||this.nowDrawingDensity,i=this.render.convertToGlobal(this.state.position),s=this.render.getRect().pageWidth,n=this.render.getRect().height;this.element.classList.remove("--simple");const h=\`\\n display: block;\\n z-index: \${this.element.style.zIndex};\\n left: 0;\\n top: 0;\\n width: \${s}px;\\n height: \${n}px;\\n \`;"hard"===e?this.drawHard(h):this.drawSoft(i,h)}drawHard(t=""){const e=this.render.getRect().left+this.render.getRect().width/2,i=this.state.hardDrawingAngle,s=t+"\\n backface-visibility: hidden;\\n -webkit-backface-visibility: hidden;\\n clip-path: none;\\n -webkit-clip-path: none;\\n "+(0===this.orientation?\`transform-origin: \${this.render.getRect().pageWidth}px 0; \\n transform: translate3d(0, 0, 0) rotateY(\${i}deg);\`:\`transform-origin: 0 0; \\n transform: translate3d(\${e}px, 0, 0) rotateY(\${i}deg);\`);this.element.style.cssText=s}drawSoft(t,e=""){let i="polygon( ";for(const t of this.state.area)if(null!==t){let e=1===this.render.getDirection()?{x:-t.x+this.state.position.x,y:t.y-this.state.position.y}:{x:t.x-this.state.position.x,y:t.y-this.state.position.y};e=h.GetRotatedPoint(e,{x:0,y:0},this.state.angle),i+=e.x+"px "+e.y+"px, "}i=i.slice(0,-2),i+=")";const s=e+\`transform-origin: 0 0; clip-path: \${i}; -webkit-clip-path: \${i};\`+(this.render.isSafari()&&0===this.state.angle?\`transform: translate(\${t.x}px, \${t.y}px);\`:\`transform: translate3d(\${t.x}px, \${t.y}px, 0) rotate(\${this.state.angle}rad);\`);this.element.style.cssText=s}simpleDraw(t){const e=this.render.getRect(),i=e.pageWidth,s=e.height,n=1===t?e.left+e.pageWidth:e.left,h=e.top;this.element.classList.add("--simple"),this.element.style.cssText=\`\\n position: absolute; \\n display: block; \\n height: \${s}px; \\n left: \${n}px; \\n top: \${h}px; \\n width: \${i}px; \\n z-index: \${this.render.getSettings().startZIndex+1};\`}getElement(){return this.element}load(){this.isLoad=!0}setOrientation(t){super.setOrientation(t),this.element.classList.remove("--left","--right"),this.element.classList.add(1===t?"--right":"--left")}setDrawingDensity(t){this.element.classList.remove("--soft","--hard"),this.element.classList.add("--"+t),super.setDrawingDensity(t)}}class o extends s{constructor(t,e,i,s){super(t,e),this.element=i,this.pagesElement=s}load(){for(const t of this.pagesElement){const e=new r(this.render,t,"hard"===t.dataset.density?"hard":"soft");e.load(),this.pages.push(e)}this.createSpread()}}class a{constructor(t,e,i,s){this.direction=t,this.corner=e,this.topIntersectPoint=null,this.sideIntersectPoint=null,this.bottomIntersectPoint=null,this.pageWidth=parseInt(i,10),this.pageHeight=parseInt(s,10)}calc(t){try{return this.position=this.calcAngleAndPosition(t),this.calculateIntersectPoint(this.position),!0}catch(t){return!1}}getFlippingClipArea(){const t=[];let e=!1;return t.push(this.rect.topLeft),t.push(this.topIntersectPoint),null===this.sideIntersectPoint?e=!0:(t.push(this.sideIntersectPoint),null===this.bottomIntersectPoint&&(e=!1)),t.push(this.bottomIntersectPoint),(e||"bottom"===this.corner)&&t.push(this.rect.bottomLeft),t}getBottomClipArea(){const t=[];return t.push(this.topIntersectPoint),"top"===this.corner?t.push({x:this.pageWidth,y:0}):(null!==this.topIntersectPoint&&t.push({x:this.pageWidth,y:0}),t.push({x:this.pageWidth,y:this.pageHeight})),null!==this.sideIntersectPoint?h.GetDistanceBetweenTwoPoint(this.sideIntersectPoint,this.topIntersectPoint)>=10&&t.push(this.sideIntersectPoint):"top"===this.corner&&t.push({x:this.pageWidth,y:this.pageHeight}),t.push(this.bottomIntersectPoint),t.push(this.topIntersectPoint),t}getAngle(){return 0===this.direction?-this.angle:this.angle}getRect(){return this.rect}getPosition(){return this.position}getActiveCorner(){return 0===this.direction?this.rect.topLeft:this.rect.topRight}getDirection(){return this.direction}getFlippingProgress(){return Math.abs((this.position.x-this.pageWidth)/(2*this.pageWidth)*100)}getCorner(){return this.corner}getBottomPagePosition(){return 1===this.direction?{x:this.pageWidth,y:0}:{x:0,y:0}}getShadowStartPoint(){return"top"===this.corner?this.topIntersectPoint:null!==this.sideIntersectPoint?this.sideIntersectPoint:this.topIntersectPoint}getShadowAngle(){const t=h.GetAngleBetweenTwoLine(this.getSegmentToShadowLine(),[{x:0,y:0},{x:this.pageWidth,y:0}]);return 0===this.direction?t:Math.PI-t}calcAngleAndPosition(t){let e=t;if(this.updateAngleAndGeometry(e),e="top"===this.corner?this.checkPositionAtCenterLine(e,{x:0,y:0},{x:0,y:this.pageHeight}):this.checkPositionAtCenterLine(e,{x:0,y:this.pageHeight},{x:0,y:0}),Math.abs(e.x-this.pageWidth)<1&&Math.abs(e.y)<1)throw new Error("Point is too small");return e}updateAngleAndGeometry(t){this.angle=this.calculateAngle(t),this.rect=this.getPageRect(t)}calculateAngle(t){const e=this.pageWidth-t.x+1,i="bottom"===this.corner?this.pageHeight-t.y:t.y;let s=2*Math.acos(e/Math.sqrt(i*i+e*e));i<0&&(s=-s);const n=Math.PI-s;if(!isFinite(s)||n>=0&&n<.003)throw new Error("The G point is too small");return"bottom"===this.corner&&(s=-s),s}getPageRect(t){return"top"===this.corner?this.getRectFromBasePoint([{x:0,y:0},{x:this.pageWidth,y:0},{x:0,y:this.pageHeight},{x:this.pageWidth,y:this.pageHeight}],t):this.getRectFromBasePoint([{x:0,y:-this.pageHeight},{x:this.pageWidth,y:-this.pageHeight},{x:0,y:0},{x:this.pageWidth,y:0}],t)}getRectFromBasePoint(t,e){return{topLeft:this.getRotatedPoint(t[0],e),topRight:this.getRotatedPoint(t[1],e),bottomLeft:this.getRotatedPoint(t[2],e),bottomRight:this.getRotatedPoint(t[3],e)}}getRotatedPoint(t,e){return{x:t.x*Math.cos(this.angle)+t.y*Math.sin(this.angle)+e.x,y:t.y*Math.cos(this.angle)-t.x*Math.sin(this.angle)+e.y}}calculateIntersectPoint(t){const e={left:-1,top:-1,width:this.pageWidth+2,height:this.pageHeight+2};"top"===this.corner?(this.topIntersectPoint=h.GetIntersectBetweenTwoSegment(e,[t,this.rect.topRight],[{x:0,y:0},{x:this.pageWidth,y:0}]),this.sideIntersectPoint=h.GetIntersectBetweenTwoSegment(e,[t,this.rect.bottomLeft],[{x:this.pageWidth,y:0},{x:this.pageWidth,y:this.pageHeight}]),this.bottomIntersectPoint=h.GetIntersectBetweenTwoSegment(e,[this.rect.bottomLeft,this.rect.bottomRight],[{x:0,y:this.pageHeight},{x:this.pageWidth,y:this.pageHeight}])):(this.topIntersectPoint=h.GetIntersectBetweenTwoSegment(e,[this.rect.topLeft,this.rect.topRight],[{x:0,y:0},{x:this.pageWidth,y:0}]),this.sideIntersectPoint=h.GetIntersectBetweenTwoSegment(e,[t,this.rect.topLeft],[{x:this.pageWidth,y:0},{x:this.pageWidth,y:this.pageHeight}]),this.bottomIntersectPoint=h.GetIntersectBetweenTwoSegment(e,[this.rect.bottomLeft,this.rect.bottomRight],[{x:0,y:this.pageHeight},{x:this.pageWidth,y:this.pageHeight}]))}checkPositionAtCenterLine(t,e,i){let s=t;const n=h.LimitPointToCircle(e,this.pageWidth,s);s!==n&&(s=n,this.updateAngleAndGeometry(s));const r=Math.sqrt(Math.pow(this.pageWidth,2)+Math.pow(this.pageHeight,2));let o=this.rect.bottomRight,a=this.rect.topLeft;if("bottom"===this.corner&&(o=this.rect.topRight,a=this.rect.bottomLeft),o.x<=0){const t=h.LimitPointToCircle(i,r,a);t!==s&&(s=t,this.updateAngleAndGeometry(s))}return s}getSegmentToShadowLine(){const t=this.getShadowStartPoint();return[t,t!==this.sideIntersectPoint&&null!==this.sideIntersectPoint?this.sideIntersectPoint:this.bottomIntersectPoint]}}class g{constructor(t,e){this.flippingPage=null,this.bottomPage=null,this.calc=null,this.state="read",this.render=t,this.app=e}fold(t){this.setState("user_fold"),null===this.calc&&this.start(t),this.do(this.render.convertToPage(t))}flip(t){if(this.app.getSettings().disableFlipByClick&&!this.isPointOnCorners(t))return;if(null!==this.calc&&this.render.finishAnimation(),!this.start(t))return;const e=this.getBoundsRect();this.setState("flipping");const i=e.height/10,s="bottom"===this.calc.getCorner()?e.height-i:i,n="bottom"===this.calc.getCorner()?e.height:0;this.calc.calc({x:e.pageWidth-i,y:s}),this.animateFlippingTo({x:e.pageWidth-i,y:s},{x:-e.pageWidth,y:n},!0)}start(t){this.reset();const e=this.render.convertToBook(t),i=this.getBoundsRect(),s=this.getDirectionByPoint(e),n=e.y>=i.height/2?"bottom":"top";if(!this.checkDirection(s))return!1;try{if(this.flippingPage=this.app.getPageCollection().getFlippingPage(s),this.bottomPage=this.app.getPageCollection().getBottomPage(s),"landscape"===this.render.getOrientation())if(1===s){const t=this.app.getPageCollection().nextBy(this.flippingPage);null!==t&&this.flippingPage.getDensity()!==t.getDensity()&&(this.flippingPage.setDrawingDensity("hard"),t.setDrawingDensity("hard"))}else{const t=this.app.getPageCollection().prevBy(this.flippingPage);null!==t&&this.flippingPage.getDensity()!==t.getDensity()&&(this.flippingPage.setDrawingDensity("hard"),t.setDrawingDensity("hard"))}return this.render.setDirection(s),this.calc=new a(s,n,i.pageWidth.toString(10),i.height.toString(10)),!0}catch(t){return!1}}do(t){if(null!==this.calc&&this.calc.calc(t)){const t=this.calc.getFlippingProgress();this.bottomPage.setArea(this.calc.getBottomClipArea()),this.bottomPage.setPosition(this.calc.getBottomPagePosition()),this.bottomPage.setAngle(0),this.bottomPage.setHardAngle(0),this.flippingPage.setArea(this.calc.getFlippingClipArea()),this.flippingPage.setPosition(this.calc.getActiveCorner()),this.flippingPage.setAngle(this.calc.getAngle()),0===this.calc.getDirection()?this.flippingPage.setHardAngle(90*(200-2*t)/100):this.flippingPage.setHardAngle(-90*(200-2*t)/100),this.render.setPageRect(this.calc.getRect()),this.render.setBottomPage(this.bottomPage),this.render.setFlippingPage(this.flippingPage),this.render.setShadowData(this.calc.getShadowStartPoint(),this.calc.getShadowAngle(),t,this.calc.getDirection())}}flipToPage(t,e){const i=this.app.getPageCollection().getCurrentSpreadIndex(),s=this.app.getPageCollection().getSpreadIndexByPage(t);try{s>i&&(this.app.getPageCollection().setCurrentSpreadIndex(s-1),this.flipNext(e)),s<i&&(this.app.getPageCollection().setCurrentSpreadIndex(s+1),this.flipPrev(e))}catch(t){}}flipNext(t){this.flip({x:this.render.getRect().left+2*this.render.getRect().pageWidth-10,y:"top"===t?1:this.render.getRect().height-2})}flipPrev(t){this.flip({x:10,y:"top"===t?1:this.render.getRect().height-2})}stopMove(){if(null===this.calc)return;const t=this.calc.getPosition(),e=this.getBoundsRect(),i="bottom"===this.calc.getCorner()?e.height:0;t.x<=0?this.animateFlippingTo(t,{x:-e.pageWidth,y:i},!0):this.animateFlippingTo(t,{x:e.pageWidth,y:i},!1)}showCorner(t){if(!this.checkState("read","fold_corner"))return;const e=this.getBoundsRect(),i=e.pageWidth;if(this.isPointOnCorners(t))if(null===this.calc){if(!this.start(t))return;this.setState("fold_corner"),this.calc.calc({x:i-1,y:1});const s=50,n="bottom"===this.calc.getCorner()?e.height-1:1,h="bottom"===this.calc.getCorner()?e.height-s:s;this.animateFlippingTo({x:i-1,y:n},{x:i-s,y:h},!1,!1)}else this.do(this.render.convertToPage(t));else this.setState("read"),this.render.finishAnimation(),this.stopMove()}animateFlippingTo(t,e,i,s=!0){const n=h.GetCordsFromTwoPoint(t,e),r=[];for(const t of n)r.push(()=>this.do(t));const o=this.getAnimationDuration(n.length);this.render.startAnimation(r,o,()=>{this.calc&&(i&&(1===this.calc.getDirection()?this.app.turnToPrevPage():this.app.turnToNextPage()),s&&(this.render.setBottomPage(null),this.render.setFlippingPage(null),this.render.clearShadow(),this.setState("read"),this.reset()))})}getCalculation(){return this.calc}getState(){return this.state}setState(t){this.state!==t&&(this.app.updateState(t),this.state=t)}getDirectionByPoint(t){const e=this.getBoundsRect();if("portrait"===this.render.getOrientation()){if(t.x-e.pageWidth<=e.width/5)return 1}else if(t.x<e.width/2)return 1;return 0}getAnimationDuration(t){const e=this.app.getSettings().flippingTime;return t>=1e3?e:t/1e3*e}checkDirection(t){return 0===t?this.app.getCurrentPageIndex()<this.app.getPageCount()-1:this.app.getCurrentPageIndex()>=1}reset(){this.calc=null,this.flippingPage=null,this.bottomPage=null}getBoundsRect(){return this.render.getRect()}checkState(...t){for(const e of t)if(this.state===e)return!0;return!1}isPointOnCorners(t){const e=this.getBoundsRect(),i=e.pageWidth,s=Math.sqrt(Math.pow(i,2)+Math.pow(e.height,2))/5,n=this.render.convertToBook(t);return n.x>0&&n.y>0&&n.x<e.width&&n.y<e.height&&(n.x<s||n.x>e.width-s)&&(n.y<s||n.y>e.height-s)}}class l{constructor(t,e){this.leftPage=null,this.rightPage=null,this.flippingPage=null,this.bottomPage=null,this.direction=null,this.orientation=null,this.shadow=null,this.animation=null,this.pageRect=null,this.boundsRect=null,this.timer=0,this.safari=!1,this.setting=e,this.app=t;const i=new RegExp("Version\\\\/[\\\\d\\\\.]+.*Safari/");this.safari=null!==i.exec(window.navigator.userAgent)}render(t){if(null!==this.animation){const e=Math.round((t-this.animation.startedAt)/this.animation.durationFrame);e<this.animation.frames.length?this.animation.frames[e]():(this.animation.onAnimateEnd(),this.animation=null)}this.timer=t,this.drawFrame()}start(){this.update();const t=e=>{this.render(e),requestAnimationFrame(t)};requestAnimationFrame(t)}startAnimation(t,e,i){this.finishAnimation(),this.animation={frames:t,duration:e,durationFrame:e/t.length,onAnimateEnd:i,startedAt:this.timer}}finishAnimation(){null!==this.animation&&(this.animation.frames[this.animation.frames.length-1](),null!==this.animation.onAnimateEnd&&this.animation.onAnimateEnd()),this.animation=null}update(){this.boundsRect=null;const t=this.calculateBoundsRect();this.orientation!==t&&(this.orientation=t,this.app.updateOrientation(t))}calculateBoundsRect(){let t="landscape";const e=this.getBlockWidth(),i=e/2,s=this.getBlockHeight()/2,n=this.setting.width/this.setting.height;let h=this.setting.width,r=this.setting.height,o=i-h;return"stretch"===this.setting.size?(e<2*this.setting.minWidth&&this.app.getSettings().usePortrait&&(t="portrait"),h="portrait"===t?this.getBlockWidth():this.getBlockWidth()/2,h>this.setting.maxWidth&&(h=this.setting.maxWidth),r=h/n,r>this.getBlockHeight()&&(r=this.getBlockHeight(),h=r*n),o="portrait"===t?i-h/2-h:i-h):e<2*h&&this.app.getSettings().usePortrait&&(t="portrait",o=i-h/2-h),this.boundsRect={left:o,top:s-r/2,width:2*h,height:r,pageWidth:h},t}setShadowData(t,e,i,s){if(!this.app.getSettings().drawShadow)return;const n=100*this.getSettings().maxShadowOpacity;this.shadow={pos:t,angle:e,width:3*this.getRect().pageWidth/4*i/100,opacity:(100-i)*n/100/100,direction:s,progress:2*i}}clearShadow(){this.shadow=null}getBlockWidth(){return this.app.getUI().getDistElement().offsetWidth}getBlockHeight(){return this.app.getUI().getDistElement().offsetHeight}getDirection(){return this.direction}getRect(){return null===this.boundsRect&&this.calculateBoundsRect(),this.boundsRect}getSettings(){return this.app.getSettings()}getOrientation(){return this.orientation}setPageRect(t){this.pageRect=t}setDirection(t){this.direction=t}setRightPage(t){null!==t&&t.setOrientation(1),this.rightPage=t}setLeftPage(t){null!==t&&t.setOrientation(0),this.leftPage=t}setBottomPage(t){null!==t&&t.setOrientation(1===this.direction?0:1),this.bottomPage=t}setFlippingPage(t){null!==t&&t.setOrientation(0===this.direction&&"portrait"!==this.orientation?0:1),this.flippingPage=t}convertToBook(t){const e=this.getRect();return{x:t.x-e.left,y:t.y-e.top}}isSafari(){return this.safari}convertToPage(t,e){e||(e=this.direction);const i=this.getRect();return{x:0===e?t.x-i.left-i.width/2:i.width/2-t.x+i.left,y:t.y-i.top}}convertToGlobal(t,e){if(e||(e=this.direction),null==t)return null;const i=this.getRect();return{x:0===e?t.x+i.left+i.width/2:i.width/2-t.x+i.left,y:t.y+i.top}}convertRectToGlobal(t,e){return e||(e=this.direction),{topLeft:this.convertToGlobal(t.topLeft,e),topRight:this.convertToGlobal(t.topRight,e),bottomLeft:this.convertToGlobal(t.bottomLeft,e),bottomRight:this.convertToGlobal(t.bottomRight,e)}}}class d extends l{constructor(t,e,i){super(t,e),this.canvas=i,this.ctx=i.getContext("2d")}getContext(){return this.ctx}reload(){}drawFrame(){this.clear(),"portrait"!==this.orientation&&null!=this.leftPage&&this.leftPage.simpleDraw(0),null!=this.rightPage&&this.rightPage.simpleDraw(1),null!=this.bottomPage&&this.bottomPage.draw(),this.drawBookShadow(),null!=this.flippingPage&&this.flippingPage.draw(),null!=this.shadow&&(this.drawOuterShadow(),this.drawInnerShadow());const t=this.getRect();"portrait"===this.orientation&&(this.ctx.beginPath(),this.ctx.rect(t.left+t.pageWidth,t.top,t.width,t.height),this.ctx.clip())}drawBookShadow(){const t=this.getRect();this.ctx.save(),this.ctx.beginPath();const e=t.width/20;this.ctx.rect(t.left,t.top,t.width,t.height);const i={x:t.left+t.width/2-e/2,y:0};this.ctx.translate(i.x,i.y);const s=this.ctx.createLinearGradient(0,0,e,0);s.addColorStop(0,"rgba(0, 0, 0, 0)"),s.addColorStop(.4,"rgba(0, 0, 0, 0.2)"),s.addColorStop(.49,"rgba(0, 0, 0, 0.1)"),s.addColorStop(.5,"rgba(0, 0, 0, 0.5)"),s.addColorStop(.51,"rgba(0, 0, 0, 0.4)"),s.addColorStop(1,"rgba(0, 0, 0, 0)"),this.ctx.clip(),this.ctx.fillStyle=s,this.ctx.fillRect(0,0,e,2*t.height),this.ctx.restore()}drawOuterShadow(){const t=this.getRect();this.ctx.save(),this.ctx.beginPath(),this.ctx.rect(t.left,t.top,t.width,t.height);const e=this.convertToGlobal({x:this.shadow.pos.x,y:this.shadow.pos.y});this.ctx.translate(e.x,e.y),this.ctx.rotate(Math.PI+this.shadow.angle+Math.PI/2);const i=this.ctx.createLinearGradient(0,0,this.shadow.width,0);0===this.shadow.direction?(this.ctx.translate(0,-100),i.addColorStop(0,"rgba(0, 0, 0, "+this.shadow.opacity+")"),i.addColorStop(1,"rgba(0, 0, 0, 0)")):(this.ctx.translate(-this.shadow.width,-100),i.addColorStop(0,"rgba(0, 0, 0, 0)"),i.addColorStop(1,"rgba(0, 0, 0, "+this.shadow.opacity+")")),this.ctx.clip(),this.ctx.fillStyle=i,this.ctx.fillRect(0,0,this.shadow.width,2*t.height),this.ctx.restore()}drawInnerShadow(){const t=this.getRect();this.ctx.save(),this.ctx.beginPath();const e=this.convertToGlobal({x:this.shadow.pos.x,y:this.shadow.pos.y}),i=this.convertRectToGlobal(this.pageRect);this.ctx.moveTo(i.topLeft.x,i.topLeft.y),this.ctx.lineTo(i.topRight.x,i.topRight.y),this.ctx.lineTo(i.bottomRight.x,i.bottomRight.y),this.ctx.lineTo(i.bottomLeft.x,i.bottomLeft.y),this.ctx.translate(e.x,e.y),this.ctx.rotate(Math.PI+this.shadow.angle+Math.PI/2);const s=3*this.shadow.width/4,n=this.ctx.createLinearGradient(0,0,s,0);0===this.shadow.direction?(this.ctx.translate(-s,-100),n.addColorStop(1,"rgba(0, 0, 0, "+this.shadow.opacity+")"),n.addColorStop(.9,"rgba(0, 0, 0, 0.05)"),n.addColorStop(.7,"rgba(0, 0, 0, "+this.shadow.opacity+")"),n.addColorStop(0,"rgba(0, 0, 0, 0)")):(this.ctx.translate(0,-100),n.addColorStop(0,"rgba(0, 0, 0, "+this.shadow.opacity+")"),n.addColorStop(.1,"rgba(0, 0, 0, 0.05)"),n.addColorStop(.3,"rgba(0, 0, 0, "+this.shadow.opacity+")"),n.addColorStop(1,"rgba(0, 0, 0, 0)")),this.ctx.clip(),this.ctx.fillStyle=n,this.ctx.fillRect(0,0,s,2*t.height),this.ctx.restore()}clear(){this.ctx.fillStyle="white",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height)}}class p{constructor(t,e,i){this.touchPoint=null,this.swipeTimeout=250,this.onResize=()=>{this.update()},this.onMouseDown=t=>{if(this.checkTarget(t.target)){const e=this.getMousePos(t.clientX,t.clientY);this.app.startUserTouch(e),t.preventDefault()}},this.onTouchStart=t=>{if(this.checkTarget(t.target)&&t.changedTouches.length>0){const e=t.changedTouches[0],i=this.getMousePos(e.clientX,e.clientY);this.touchPoint={point:i,time:Date.now()},setTimeout(()=>{null!==this.touchPoint&&this.app.startUserTouch(i)},this.swipeTimeout),this.app.getSettings().mobileScrollSupport||t.preventDefault()}},this.onMouseUp=t=>{const e=this.getMousePos(t.clientX,t.clientY);this.app.userStop(e)},this.onMouseMove=t=>{const e=this.getMousePos(t.clientX,t.clientY);this.app.userMove(e,!1)},this.onTouchMove=t=>{if(t.changedTouches.length>0){const e=t.changedTouches[0],i=this.getMousePos(e.clientX,e.clientY);this.app.getSettings().mobileScrollSupport?(null!==this.touchPoint&&(Math.abs(this.touchPoint.point.x-i.x)>10||"read"!==this.app.getState())&&t.cancelable&&this.app.userMove(i,!0),"read"!==this.app.getState()&&t.preventDefault()):this.app.userMove(i,!0)}},this.onTouchEnd=t=>{if(t.changedTouches.length>0){const e=t.changedTouches[0],i=this.getMousePos(e.clientX,e.clientY);let s=!1;if(null!==this.touchPoint){const t=i.x-this.touchPoint.point.x,e=Math.abs(i.y-this.touchPoint.point.y);Math.abs(t)>this.swipeDistance&&e<2*this.swipeDistance&&Date.now()-this.touchPoint.time<this.swipeTimeout&&(t>0?this.app.flipPrev(this.touchPoint.point.y<this.app.getRender().getRect().height/2?"top":"bottom"):this.app.flipNext(this.touchPoint.point.y<this.app.getRender().getRect().height/2?"top":"bottom"),s=!0),this.touchPoint=null}this.app.userStop(i,s)}},this.parentElement=t,t.classList.add("stf__parent"),t.insertAdjacentHTML("afterbegin",'<div class="stf__wrapper"></div>'),this.wrapper=t.querySelector(".stf__wrapper"),this.app=e;const s=this.app.getSettings().usePortrait?1:2;t.style.minWidth=i.minWidth*s+"px",t.style.minHeight=i.minHeight+"px","fixed"===i.size&&(t.style.minWidth=i.width*s+"px",t.style.minHeight=i.height+"px"),i.autoSize&&(t.style.width="100%",t.style.maxWidth=2*i.maxWidth+"px"),t.style.display="block",window.addEventListener("resize",this.onResize,!1),this.swipeDistance=i.swipeDistance}destroy(){this.app.getSettings().useMouseEvents&&this.removeHandlers(),this.distElement.remove(),this.wrapper.remove()}getDistElement(){return this.distElement}getWrapper(){return this.wrapper}setOrientationStyle(t){this.wrapper.classList.remove("--portrait","--landscape"),"portrait"===t?(this.app.getSettings().autoSize&&(this.wrapper.style.paddingBottom=this.app.getSettings().height/this.app.getSettings().width*100+"%"),this.wrapper.classList.add("--portrait")):(this.app.getSettings().autoSize&&(this.wrapper.style.paddingBottom=this.app.getSettings().height/(2*this.app.getSettings().width)*100+"%"),this.wrapper.classList.add("--landscape")),this.update()}removeHandlers(){window.removeEventListener("resize",this.onResize),this.distElement.removeEventListener("mousedown",this.onMouseDown),this.distElement.removeEventListener("touchstart",this.onTouchStart),window.removeEventListener("mousemove",this.onMouseMove),window.removeEventListener("touchmove",this.onTouchMove),window.removeEventListener("mouseup",this.onMouseUp),window.removeEventListener("touchend",this.onTouchEnd)}setHandlers(){window.addEventListener("resize",this.onResize,!1),this.app.getSettings().useMouseEvents&&(this.distElement.addEventListener("mousedown",this.onMouseDown),this.distElement.addEventListener("touchstart",this.onTouchStart),window.addEventListener("mousemove",this.onMouseMove),window.addEventListener("touchmove",this.onTouchMove,{passive:!this.app.getSettings().mobileScrollSupport}),window.addEventListener("mouseup",this.onMouseUp),window.addEventListener("touchend",this.onTouchEnd))}getMousePos(t,e){const i=this.distElement.getBoundingClientRect();return{x:t-i.left,y:e-i.top}}checkTarget(t){return!this.app.getSettings().clickEventForward||!["a","button"].includes(t.tagName.toLowerCase())}}class c extends p{constructor(t,e,i,s){super(t,e,i),this.wrapper.insertAdjacentHTML("afterbegin",'<div class="stf__block"></div>'),this.distElement=t.querySelector(".stf__block"),this.items=s;for(const t of s)this.distElement.appendChild(t);this.setHandlers()}clear(){for(const t of this.items)this.parentElement.appendChild(t)}updateItems(t){this.removeHandlers(),this.distElement.innerHTML="";for(const e of t)this.distElement.appendChild(e);this.items=t,this.setHandlers()}update(){this.app.getRender().update()}}class u extends p{constructor(t,e,i){super(t,e,i),this.wrapper.innerHTML='<canvas class="stf__canvas"></canvas>',this.canvas=t.querySelectorAll("canvas")[0],this.distElement=this.canvas,this.resizeCanvas(),this.setHandlers()}resizeCanvas(){const t=getComputedStyle(this.canvas),e=parseInt(t.getPropertyValue("width"),10),i=parseInt(t.getPropertyValue("height"),10);this.canvas.width=e,this.canvas.height=i}getCanvas(){return this.canvas}update(){this.resizeCanvas(),this.app.getRender().update()}}class w extends l{constructor(t,e,i){super(t,e),this.outerShadow=null,this.innerShadow=null,this.hardShadow=null,this.hardInnerShadow=null,this.element=i,this.createShadows()}createShadows(){this.element.insertAdjacentHTML("beforeend",'<div class="stf__outerShadow"></div>\\n <div class="stf__innerShadow"></div>\\n <div class="stf__hardShadow"></div>\\n <div class="stf__hardInnerShadow"></div>'),this.outerShadow=this.element.querySelector(".stf__outerShadow"),this.innerShadow=this.element.querySelector(".stf__innerShadow"),this.hardShadow=this.element.querySelector(".stf__hardShadow"),this.hardInnerShadow=this.element.querySelector(".stf__hardInnerShadow")}clearShadow(){super.clearShadow(),this.outerShadow.style.cssText="display: none",this.innerShadow.style.cssText="display: none",this.hardShadow.style.cssText="display: none",this.hardInnerShadow.style.cssText="display: none"}reload(){this.element.querySelector(".stf__outerShadow")||this.createShadows()}drawHardInnerShadow(){const t=this.getRect(),e=this.shadow.progress>100?200-this.shadow.progress:this.shadow.progress;let i=(100-e)*(2.5*t.pageWidth)/100+20;i>t.pageWidth&&(i=t.pageWidth);let s=\`\\n display: block;\\n z-index: \${(this.getSettings().startZIndex+5).toString(10)};\\n width: \${i}px;\\n height: \${t.height}px;\\n background: linear-gradient(to right,\\n rgba(0, 0, 0, \${this.shadow.opacity*e/100}) 5%,\\n rgba(0, 0, 0, 0) 100%);\\n left: \${t.left+t.width/2}px;\\n transform-origin: 0 0;\\n \`;s+=0===this.getDirection()&&this.shadow.progress>100||1===this.getDirection()&&this.shadow.progress<=100?"transform: translate3d(0, 0, 0);":"transform: translate3d(0, 0, 0) rotateY(180deg);",this.hardInnerShadow.style.cssText=s}drawHardOuterShadow(){const t=this.getRect();let e=(100-(this.shadow.progress>100?200-this.shadow.progress:this.shadow.progress))*(2.5*t.pageWidth)/100+20;e>t.pageWidth&&(e=t.pageWidth);let i=\`\\n display: block;\\n z-index: \${(this.getSettings().startZIndex+4).toString(10)};\\n width: \${e}px;\\n height: \${t.height}px;\\n background: linear-gradient(to left, rgba(0, 0, 0, \${this.shadow.opacity}) 5%, rgba(0, 0, 0, 0) 100%);\\n left: \${t.left+t.width/2}px;\\n transform-origin: 0 0;\\n \`;i+=0===this.getDirection()&&this.shadow.progress>100||1===this.getDirection()&&this.shadow.progress<=100?"transform: translate3d(0, 0, 0) rotateY(180deg);":"transform: translate3d(0, 0, 0);",this.hardShadow.style.cssText=i}drawInnerShadow(){const t=this.getRect(),e=3*this.shadow.width/4,i=0===this.getDirection()?e:0,s=0===this.getDirection()?"to left":"to right",n=this.convertToGlobal(this.shadow.pos),r=this.shadow.angle+3*Math.PI/2,o=[this.pageRect.topLeft,this.pageRect.topRight,this.pageRect.bottomRight,this.pageRect.bottomLeft];let a="polygon( ";for(const t of o){let e=1===this.getDirection()?{x:-t.x+this.shadow.pos.x,y:t.y-this.shadow.pos.y}:{x:t.x-this.shadow.pos.x,y:t.y-this.shadow.pos.y};e=h.GetRotatedPoint(e,{x:i,y:100},r),a+=e.x+"px "+e.y+"px, "}a=a.slice(0,-2),a+=")";const g=\`\\n display: block;\\n z-index: \${(this.getSettings().startZIndex+10).toString(10)};\\n width: \${e}px;\\n height: \${2*t.height}px;\\n background: linear-gradient(\${s},\\n rgba(0, 0, 0, \${this.shadow.opacity}) 5%,\\n rgba(0, 0, 0, 0.05) 15%,\\n rgba(0, 0, 0, \${this.shadow.opacity}) 35%,\\n rgba(0, 0, 0, 0) 100%);\\n transform-origin: \${i}px 100px;\\n transform: translate3d(\${n.x-i}px, \${n.y-100}px, 0) rotate(\${r}rad);\\n clip-path: \${a};\\n -webkit-clip-path: \${a};\\n \`;this.innerShadow.style.cssText=g}drawOuterShadow(){const t=this.getRect(),e=this.convertToGlobal({x:this.shadow.pos.x,y:this.shadow.pos.y}),i=this.shadow.angle+3*Math.PI/2,s=1===this.getDirection()?this.shadow.width:0,n=0===this.getDirection()?"to right":"to left",r=[{x:0,y:0},{x:t.pageWidth,y:0},{x:t.pageWidth,y:t.height},{x:0,y:t.height}];let o="polygon( ";for(const t of r)if(null!==t){let e=1===this.getDirection()?{x:-t.x+this.shadow.pos.x,y:t.y-this.shadow.pos.y}:{x:t.x-this.shadow.pos.x,y:t.y-this.shadow.pos.y};e=h.GetRotatedPoint(e,{x:s,y:100},i),o+=e.x+"px "+e.y+"px, "}o=o.slice(0,-2),o+=")";const a=\`\\n display: block;\\n z-index: \${(this.getSettings().startZIndex+10).toString(10)};\\n width: \${this.shadow.width}px;\\n height: \${2*t.height}px;\\n background: linear-gradient(\${n}, rgba(0, 0, 0, \${this.shadow.opacity}), rgba(0, 0, 0, 0));\\n transform-origin: \${s}px 100px;\\n transform: translate3d(\${e.x-s}px, \${e.y-100}px, 0) rotate(\${i}rad);\\n clip-path: \${o};\\n -webkit-clip-path: \${o};\\n \`;this.outerShadow.style.cssText=a}drawLeftPage(){"portrait"!==this.orientation&&null!==this.leftPage&&(1===this.direction&&null!==this.flippingPage&&"hard"===this.flippingPage.getDrawingDensity()?(this.leftPage.getElement().style.zIndex=(this.getSettings().startZIndex+5).toString(10),this.leftPage.setHardDrawingAngle(180+this.flippingPage.getHardAngle()),this.leftPage.draw(this.flippingPage.getDrawingDensity())):this.leftPage.simpleDraw(0))}drawRightPage(){null!==this.rightPage&&(0===this.direction&&null!==this.flippingPage&&"hard"===this.flippingPage.getDrawingDensity()?(this.rightPage.getElement().style.zIndex=(this.getSettings().startZIndex+5).toString(10),this.rightPage.setHardDrawingAngle(180+this.flippingPage.getHardAngle()),this.rightPage.draw(this.flippingPage.getDrawingDensity())):this.rightPage.simpleDraw(1))}drawBottomPage(){if(null===this.bottomPage)return;const t=null!=this.flippingPage?this.flippingPage.getDrawingDensity():null;"portrait"===this.orientation&&1===this.direction||(this.bottomPage.getElement().style.zIndex=(this.getSettings().startZIndex+3).toString(10),this.bottomPage.draw(t))}drawFrame(){this.clear(),this.drawLeftPage(),this.drawRightPage(),this.drawBottomPage(),null!=this.flippingPage&&(this.flippingPage.getElement().style.zIndex=(this.getSettings().startZIndex+5).toString(10),this.flippingPage.draw()),null!=this.shadow&&null!==this.flippingPage&&("soft"===this.flippingPage.getDrawingDensity()?(this.drawOuterShadow(),this.drawInnerShadow()):(this.drawHardOuterShadow(),this.drawHardInnerShadow()))}clear(){for(const t of this.app.getPageCollection().getPages())t!==this.leftPage&&t!==this.rightPage&&t!==this.flippingPage&&t!==this.bottomPage&&(t.getElement().style.cssText="display: none"),t.getTemporaryCopy()!==this.flippingPage&&t.hideTemporaryCopy()}update(){super.update(),null!==this.rightPage&&this.rightPage.setOrientation(1),null!==this.leftPage&&this.leftPage.setOrientation(0)}}class x{constructor(){this._default={startPage:0,size:"fixed",width:0,height:0,minWidth:0,maxWidth:0,minHeight:0,maxHeight:0,drawShadow:!0,flippingTime:1e3,usePortrait:!0,startZIndex:0,autoSize:!0,maxShadowOpacity:1,showCover:!1,mobileScrollSupport:!0,swipeDistance:30,clickEventForward:!0,useMouseEvents:!0,showPageCorners:!0,disableFlipByClick:!1}}getSettings(t){const e=this._default;if(Object.assign(e,t),"stretch"!==e.size&&"fixed"!==e.size)throw new Error('Invalid size type. Available only "fixed" and "stretch" value');if(e.width<=0||e.height<=0)throw new Error("Invalid width or height");if(e.flippingTime<=0)throw new Error("Invalid flipping time");return"stretch"===e.size?(e.minWidth<=0&&(e.minWidth=100),e.maxWidth<e.minWidth&&(e.maxWidth=2e3),e.minHeight<=0&&(e.minHeight=100),e.maxHeight<e.minHeight&&(e.maxHeight=2e3)):(e.minWidth=e.width,e.maxWidth=e.width,e.minHeight=e.height,e.maxHeight=e.height),e}}!function(t,e){void 0===e&&(e={});var i=e.insertAt;if(t&&"undefined"!=typeof document){var s=document.head||document.getElementsByTagName("head")[0],n=document.createElement("style");n.type="text/css","top"===i&&s.firstChild?s.insertBefore(n,s.firstChild):s.appendChild(n),n.styleSheet?n.styleSheet.cssText=t:n.appendChild(document.createTextNode(t))}}(".stf__parent {\\n position: relative;\\n display: block;\\n box-sizing: border-box;\\n transform: translateZ(0);\\n\\n -ms-touch-action: pan-y;\\n touch-action: pan-y;\\n}\\n\\n.sft__wrapper {\\n position: relative;\\n width: 100%;\\n box-sizing: border-box;\\n}\\n\\n.stf__parent canvas {\\n position: absolute;\\n width: 100%;\\n height: 100%;\\n left: 0;\\n top: 0;\\n}\\n\\n.stf__block {\\n position: absolute;\\n width: 100%;\\n height: 100%;\\n box-sizing: border-box;\\n perspective: 2000px;\\n}\\n\\n.stf__item {\\n display: none;\\n position: absolute;\\n transform-style: preserve-3d;\\n}\\n\\n.stf__outerShadow {\\n position: absolute;\\n left: 0;\\n top: 0;\\n}\\n\\n.stf__innerShadow {\\n position: absolute;\\n left: 0;\\n top: 0;\\n}\\n\\n.stf__hardShadow {\\n position: absolute;\\n left: 0;\\n top: 0;\\n}\\n\\n.stf__hardInnerShadow {\\n position: absolute;\\n left: 0;\\n top: 0;\\n}");t.PageFlip=class extends class{constructor(){this.events=new Map}on(t,e){return this.events.has(t)?this.events.get(t).push(e):this.events.set(t,[e]),this}off(t){this.events.delete(t)}trigger(t,e,i=null){if(this.events.has(t))for(const s of this.events.get(t))s({data:i,object:e})}}{constructor(t,e){super(),this.isUserTouch=!1,this.isUserMove=!1,this.setting=null,this.pages=null,this.setting=(new x).getSettings(e),this.block=t}destroy(){this.ui.destroy(),this.block.remove()}update(){this.render.update(),this.pages.show()}loadFromImages(t){this.ui=new u(this.block,this,this.setting);const e=this.ui.getCanvas();this.render=new d(this,this.setting,e),this.flipController=new g(this.render,this),this.pages=new n(this,this.render,t),this.pages.load(),this.render.start(),this.pages.show(this.setting.startPage),setTimeout(()=>{this.ui.update(),this.trigger("init",this,{page:this.setting.startPage,mode:this.render.getOrientation()})},1)}loadFromHTML(t){this.ui=new c(this.block,this,this.setting,t),this.render=new w(this,this.setting,this.ui.getDistElement()),this.flipController=new g(this.render,this),this.pages=new o(this,this.render,this.ui.getDistElement(),t),this.pages.load(),this.render.start(),this.pages.show(this.setting.startPage),setTimeout(()=>{this.ui.update(),this.trigger("init",this,{page:this.setting.startPage,mode:this.render.getOrientation()})},1)}updateFromImages(t){const e=this.pages.getCurrentPageIndex();this.pages.destroy(),this.pages=new n(this,this.render,t),this.pages.load(),this.pages.show(e),this.trigger("update",this,{page:e,mode:this.render.getOrientation()})}updateFromHtml(t){const e=this.pages.getCurrentPageIndex();this.pages.destroy(),this.pages=new o(this,this.render,this.ui.getDistElement(),t),this.pages.load(),this.ui.updateItems(t),this.render.reload(),this.pages.show(e),this.trigger("update",this,{page:e,mode:this.render.getOrientation()})}clear(){this.pages.destroy(),this.ui.clear()}turnToPrevPage(){this.pages.showPrev()}turnToNextPage(){this.pages.showNext()}turnToPage(t){this.pages.show(t)}flipNext(t="top"){this.flipController.flipNext(t)}flipPrev(t="top"){this.flipController.flipPrev(t)}flip(t,e="top"){this.flipController.flipToPage(t,e)}updateState(t){this.trigger("changeState",this,t)}updatePageIndex(t){this.trigger("flip",this,t)}updateOrientation(t){this.ui.setOrientationStyle(t),this.update(),this.trigger("changeOrientation",this,t)}getPageCount(){return this.pages.getPageCount()}getCurrentPageIndex(){return this.pages.getCurrentPageIndex()}getPage(t){return this.pages.getPage(t)}getRender(){return this.render}getFlipController(){return this.flipController}getOrientation(){return this.render.getOrientation()}getBoundsRect(){return this.render.getRect()}getSettings(){return this.setting}getUI(){return this.ui}getState(){return this.flipController.getState()}getPageCollection(){return this.pages}startUserTouch(t){this.mousePosition=t,this.isUserTouch=!0,this.isUserMove=!1}userMove(t,e){this.isUserTouch||e||!this.setting.showPageCorners?this.isUserTouch&&h.GetDistanceBetweenTwoPoint(this.mousePosition,t)>5&&(this.isUserMove=!0,this.flipController.fold(t)):this.flipController.showCorner(t)}userStop(t,e=!1){this.isUserTouch&&(this.isUserTouch=!1,e||(this.isUserMove?this.flipController.stopMove():this.flipController.flip(t)))}},Object.defineProperty(t,"__esModule",{value:!0})}));
<\/script>
<script>
(function(){
const frame = document.getElementById('frame');
const flipEl = document.getElementById('flip');
const prevB = document.getElementById('prev');
const nextB = document.getElementById('next');
const sectEl = document.getElementById('sect');
const countEl = document.getElementById('count');
const prog = document.getElementById('prog');
const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
// running header/footer + wrap each page for the flip engine
const sections = Array.from(flipEl.querySelectorAll('.page'));
const N = sections.length;
const titles = sections.map(s=>s.dataset.title);
sections.forEach((pg,i)=>{
if(!pg.classList.contains('cover')){
const head = document.createElement('div');
head.className='pg-head';
head.innerHTML = '<span class="wm">GOTHAM BUILDING</span><span class="pj">EDMONDSON VILLAGE — PAD 1</span>';
const foot = document.createElement('div');
foot.className='pg-foot';
foot.innerHTML = '<span class="tag">Save Money. Save Time. Stay in Control.</span><span class="no">PAGE <b>'+(i+1)+'</b></span>';
pg.insertBefore(head, pg.firstChild);
pg.appendChild(foot);
}
const wrap = document.createElement('div');
wrap.className = 'sheetpage ' + (i%2===0 ? 'pg-right' : 'pg-left');
wrap.dataset.density = 'soft';
pg.parentNode.insertBefore(wrap, pg);
wrap.appendChild(pg);
});
function frameSize(){
const availH = window.innerHeight - 118;
const availW = window.innerWidth - 110;
const landscape = availW > 520 && availH >= 430; // short screens read better as a single page
let ph, pw;
if(landscape){
ph = Math.min(availH, 720); pw = ph * 0.7727;
if(2*pw > availW){ pw = availW/2; ph = pw/0.7727; }
frame.style.width = (2*pw)+'px';
} else {
pw = Math.min(window.innerWidth - 24, 440);
ph = Math.min(availH, pw/0.7727); pw = ph * 0.7727;
frame.style.width = pw+'px';
}
frame.style.height = ph+'px';
return {pw, ph};
}
frameSize();
const pageFlip = new St.PageFlip(flipEl, {
width: 510, height: 660,
size: 'stretch',
minWidth: 220, maxWidth: 1000,
minHeight: 285, maxHeight: 1294,
showCover: true,
usePortrait: true,
flippingTime: reduced ? 1 : 850,
maxShadowOpacity: 0.5,
showPageCorners: true,
swipeDistance: 24,
mobileScrollSupport: false
});
pageFlip.loadFromHTML(document.querySelectorAll('#flip .sheetpage'));
function setFontScale(){
const item = flipEl.querySelector('.stf__item');
const h = item ? item.getBoundingClientRect().height : parseFloat(frame.style.height);
if(h>0) document.documentElement.style.setProperty('--fs', (h*0.0158)+'px');
}
function hud(){
const idx = pageFlip.getCurrentPageIndex();
const portrait = pageFlip.getOrientation && pageFlip.getOrientation()==='portrait';
if(portrait){
sectEl.textContent = idx===0 ? 'Cover' : titles[idx];
countEl.textContent = (idx+1)+' / '+N;
} else {
if(idx<=0){ sectEl.textContent='Cover'; countEl.textContent='1 / '+N; }
else if(idx>=N-1){ sectEl.textContent=titles[N-1]; countEl.textContent=N+' / '+N; }
else{
const L=idx+1, R=Math.min(idx+2,N);
sectEl.textContent = titles[R-1];
countEl.textContent = L+'\\u2013'+R+' / '+N;
}
}
prevB.disabled = idx<=0;
nextB.disabled = idx>=N-1;
prog.style.width = (idx/(N-1)*100)+'%';
}
pageFlip.on('flip', hud);
pageFlip.on('changeOrientation', ()=>{ setTimeout(()=>{ setFontScale(); hud(); }, 60); });
pageFlip.on('changeState', e=>{ flipEl.classList.toggle('clip', e.data==='read'); });
prevB.onclick = ()=>pageFlip.flipPrev();
nextB.onclick = ()=>pageFlip.flipNext();
document.addEventListener('keydown', e=>{
if(e.key==='ArrowRight'||e.key==='PageDown'){e.preventDefault();pageFlip.flipNext();}
if(e.key==='ArrowLeft'||e.key==='PageUp'){e.preventDefault();pageFlip.flipPrev();}
});
let rT=null;
window.addEventListener('resize', ()=>{
frameSize();
clearTimeout(rT);
rT=setTimeout(()=>{ setFontScale(); hud(); }, 220);
});
window.addEventListener('orientationchange', ()=>setTimeout(()=>{ frameSize(); setFontScale(); hud(); }, 300));
setTimeout(()=>{ setFontScale(); hud(); flipEl.classList.add('clip'); }, 60);
})();
<\/script>
</body>
</html>
`;
var f = document.createElement('iframe');
f.setAttribute('title','Gotham Building — Edmondson Village Pad 1 Proposal');
f.setAttribute('style','position:fixed;top:0;left:0;width:100vw;height:100vh;height:100dvh;border:0;margin:0;padding:0;z-index:2147483000;background:#0D0D0D;');
f.setAttribute('allow','fullscreen');
f.srcdoc = html;
document.body.appendChild(f);
document.documentElement.style.overflow = 'hidden';
document.body.style.overflow = 'hidden';
})();
</script>
PROJECT MANAGEMENT PROPOSAL
VILLAGE — PAD 1
Executive Summary
Gotham Building Project Management Services has completed an initial review of the available Edmondson Village Pad 1 bid, permit, specification, structural, MEP, sustainability, and related project documents. The project design intent is generally understandable and the project can move forward. The current bid package, however, contains coordination issues, scope ambiguities, and commercial inconsistencies that should be resolved before final pricing and contract award.
The principal Owner risk is not any single drafting error. It is that bidders may interpret unresolved requirements differently. That can produce bids that appear comparable but carry materially different scopes, followed by exclusions, change orders, procurement impacts, or schedule disputes after award.
Gotham proposes to provide the Owner with an independent project-control function through preconstruction, procurement, construction, and closeout. The objective is to establish one documented bid basis, assign responsibilities, normalize bids, preserve the project record, independently test changes and delays, and drive unresolved issues to timely decisions.
Why This Matters
| Ambiguous Document | Bidder Assumption | Contract Scope Gap | Change / Delay |
|---|---|---|---|
| Unresolved requirement | Different pricing basis | Exclusion survives award | Owner exposure increases |
Gotham’s objective is to interrupt this sequence before contract award.
Gotham’s Role
The Architect remains responsible for design and interpretation of the Contract Documents. The Contractor remains responsible for construction, means and methods, sequencing, coordination, safety, subcontractor management, and contractual performance. Gotham represents the Owner by managing the space between those responsibilities: scope, decisions, cost, schedule, documentation, accountability, and unresolved risk.
Phase I — Preconstruction & Bid Package Coordination
Document Control & Risk Review
Establish the current project record and maintain a consolidated Preconstruction Risk & Clarification Log identifying document conflicts, missing information, scope ambiguities, trade interfaces, shell/tenant boundaries, delegated design, testing, procurement, and schedule exposure.
Design Clarification / RFI Management
Consolidate bid-critical questions and coordinate written resolution with the Architect, engineers, Owner, and responsible consultants so all bidders price the same answer.
Scope Responsibility Matrix
Define Furnish, Install, Coordinate, Engineer, Permit, Test/Inspect, Protect, and Warranty responsibility for major systems and interfaces.
Bid Package Coordination
Carry material clarifications into addenda, scope sheets, bidder instructions, and contract exhibits so known ambiguities do not survive award.
Phase II — Bidding, Leveling & Award
Gotham will evaluate the complete bid basis, not simply the bottom-line number. Proposals will be reviewed for inclusions, exclusions, qualifications, allowances, alternates, substitutions, unit prices, schedule assumptions, long-lead items, bonding/insurance, delegated design, testing, permits, and closeout.
| Illustrative Bid Leveling | Bidder A | Bidder B | Bidder C |
|---|---|---|---|
| Submitted Bid | $1.000M | $0.940M | $0.975M |
| Missing / Excluded Scope | $0.020M | $0.105M | $0.035M |
| Normalized Cost | $1.020M | $1.045M | $1.010M |
Phase III — Construction Project Management
Cost Control
Maintain Owner cost reporting and independently evaluate proposed changes against original scope, authorization, notice, quantities, labor/material support, markup, and schedule effect.
Schedule Control
Review baseline and updates against Owner milestones; track design decisions, submittals, procurement, utilities, inspections, commissioning, and turnover. Delay assertions are tested against actual activities, dates, critical-path effect, concurrency, and mitigation.
Project Administration
Manage or monitor Owner/Architect/Contractor meetings, action logs, RFIs, submittals, decisions, procurement, payment applications, testing, inspections, deficiencies, and unresolved issues.
Quality & Envelope Control
Coordinate preinstallation meetings, mockups, WRB transitions, flashing, storefront interfaces, roof/wall transitions, penetrations, sealants, canopy attachments, manufacturer requirements, and required inspections before concealment.
IGCC, Commissioning & Closeout
Establish responsibility and due dates for IGCC records, commissioning/FPT, waste-management documentation, inspections, test reports, warranties, O&M information, record documents, punch list, and permit/AHJ closeout.
Owner Reporting
Gotham will provide concise executive reporting centered on decisions and exposure:
- COST—Budget, commitments, pending changes, forecast exposure, and forecast final cost.
- SCHEDULE—Current status, milestone variance, critical risks, and recovery actions.
- PROCUREMENT—Long-lead status and decisions required.
- DECISIONS—Owner/design decisions, responsible party, required date, and consequence of delay.
- CHANGES—Approved, pending, disputed, and forecast changes.
- QUALITY—Inspections, deficiencies, envelope issues, and close-in hold points.
- RISK—Items capable of materially affecting cost, completion, or turnover.
Immediate 30-Day Action Plan
| Week | Focus | Actions |
|---|---|---|
| WEEK 1 | Establish the Record | Confirm current documents/addenda; establish document register; open risk and decision logs. |
| WEEK 2 | Resolve Bid-Critical Questions | Consolidate and drive clarification of shell/tenant scope, assemblies, hardware, envelope interfaces, interiors, and commercial-document issues. |
| WEEK 3 | Establish Common Bid Basis | Finalize responsibility matrix, bidder scope sheets, milestone schedule, procurement requirements, and addendum items. |
| WEEK 4 | Bid & Award Control | Normalize bids, identify exclusions, conduct scope reviews, and prepare the Owner’s award recommendation. |
Commercial Logic for the Owner
Before award, an ambiguity is a question. After award, the same ambiguity can become a change order. After procurement or installation begins, it can become a change order plus schedule impact. Gotham’s initial priority is therefore to move project risk upstream, where it is less expensive to resolve.
Proposed Fee Structure
| Service | Basis | Fee |
|---|---|---|
| Phase I — Preconstruction / Bid Package Coordination | Fixed Fee | $________ |
| Phase II — Bid Leveling / Procurement / Award | Fixed Fee | $________ |
| Phase III — Construction Project Management | Monthly; anticipated ____ months | $________ / month |
Additional Services: only upon written Owner authorization, at agreed hourly rates or a negotiated lump sum.
Assumptions & Limits
- Gotham’s services are project management and owner’s representation; they do not replace architectural, engineering, legal, safety, or contractor responsibilities.
- Design interpretations and revisions remain the responsibility of the design professionals of record.
- Contractor means, methods, sequencing, site safety, subcontractor performance, and construction execution remain the Contractor’s responsibility.
- Legal conclusions regarding breach, default, negligence, waiver, or other legal rights are outside this proposal and should be reviewed by Owner’s counsel when required.
- Final scope, schedule, staffing level, meeting cadence, and fee will be confirmed with the Owner before execution.
Authorization
Gotham’s objective is to identify material issues early, establish responsibility, document decisions, understand cost and schedule consequences, and drive unresolved matters to closure.
[CLIENT NAME]
PROJECT MANAGEMENT SERVICES
Appendix A — Preliminary Risk Register
This appendix summarizes selected items identified during Gotham’s preliminary review. It is not a substitute for the complete coordinated document review proposed in Phase I.
| Priority | Issue | Current Concern | Owner | Required Action |
|---|---|---|---|---|
| CRITICAL | Project address | 4404 vs. 4522 Edmondson Avenue references | Architect / Owner | Confirm and reissue affected documents |
| CRITICAL | Contract / bid information | Obsolete dates and incomplete/inconsistent commercial documents | Owner / GC / Architect | Issue current bid milestones and complete contract basis |
| CRITICAL | Shell / tenant interface | Slab identified as tenant work while under-slab insulation/vapor-retarder requirements appear in specifications | Architect / Owner | Define responsibility and sequencing |
| CRITICAL | Exterior sheathing | OSB/plywood vs. exterior gypsum requirements | Architect / Structural | Confirm intended wall assembly |
| HIGH | Door hardware | Residential template content does not align with shell project | Architect | Issue project-specific D1/D2 hardware sets |
Appendix A — Preliminary Risk Register (continued)
| Priority | Issue | Current Concern | Owner | Required Action |
|---|---|---|---|---|
| HIGH | Interior scope | Drywall, paint, base and signage applicability is unclear against tenant-fit-out limits | Architect / Owner | Issue shell finish schedule |
| HIGH | Envelope interfaces | Multiple trades share WRB, masonry, rainscreen, storefront, flashing, sealants and roofing interfaces | GC / Architect | Issue responsibility matrix and coordinate details |
| HIGH | Canopy | Delegated-design, attachment, flashing and structural coordination require definition | Architect / Structural / Supplier | Confirm criteria and responsibility |
| HIGH | MEP document status | Some permit MEP information is marked Not for Construction | Design Team / Owner | Define bid/IFC status and change treatment |
| MEDIUM | IGCC / commissioning | Requirements exist but execution, documentation and trade allocation require active management | GC / Gotham | Establish compliance/closeout matrix |
Appendix B — Client Transmittal Email
Subject: Edmondson Village Pad 1 — Preconstruction Review & Recommended Owner PM Support
Hi [Client Name],
We completed an initial review of the Edmondson Village Pad 1 bid and permit documents. The project itself is straightforward and the overall design intent is understandable. However, the current bid package contains several coordination and scope issues that should be resolved before final pricing and contract award.
The concern is less about individual drafting errors and more about their commercial effect. The current record includes inconsistencies involving project identification, shell-versus-tenant scope, building-envelope assemblies and trade interfaces, door/hardware requirements, interior finish scope, contract requirements, and bid/schedule information.
None of these issues is unusual or necessarily expensive to correct during preconstruction. The risk comes from allowing bidders to resolve them through their own assumptions. That can result in bids that appear competitive but contain materially different scopes, followed by exclusions, change orders, or schedule impacts after award.
Gotham can provide value by establishing a single, documented bid basis before the Owner commits construction dollars. Our recommended approach is to complete the document review, consolidate bid-critical RFIs, establish a scope-responsibility matrix, coordinate responses with the design team, level contractor proposals, and carry the resulting clarifications into the final contract scope.
If retained through construction, Gotham would continue as the Owner’s project-management representative, independently monitoring cost, schedule, procurement, RFIs/submittals, change orders, payment applications, quality-control milestones, IGCC/commissioning requirements, and closeout.
The attached proposal outlines our recommended approach. The objective is simple: resolve ambiguity while it is still a question, rather than after it becomes a change order or delay.
Best,
[Name]
Gotham Building Project Management Services
[Phone] | [Email]