From d759ecbefc66f2047df2c23e3f0634e2c1ffbfac Mon Sep 17 00:00:00 2001 From: DemchaAV Date: Thu, 8 Oct 2026 11:24:47 +0100 Subject: [PATCH 1/3] fix(docx): set what follows a panel where the page does, and name the rest Word sets a panel's content below its whole top border and its margin, and ends the row its margin and its whole bottom border past the content; the page strokes each border on the panel's edge. Half a border, and as much of its inner half as the padding falls short of it, reaches past the panel's box. The export took each border whole out of the space round the panel: a padded card with a gap below it stood what followed half a border high, unnamed. - The reach comes out of the space round the panel, then the panel's padding (the cell margin), then, above, the room over its first line; what none of them takes is named, on the panel for its top border and on the block below for its bottom one ("space above"). - A panel holds the page's height less its padding as its row's height, which Word and LibreOffice read as the content's; a shape container holds its outline's height less both borders and its margins, its borders inside it. - What a panel's content leaves below itself - a line held to an icon, a card's border ending it - comes out of the room the page leaves under that content, then its padding below; a card's border ending a row's cell reaches past the row only by what the row's room under that cell does not hold. - The paragraph Word keeps between two tables is named where the space between them does not take it, together with a border reaching the same block; a container's top edge above a table counts as that space. - A margin below zero under a panel pulls what follows up and is no border; a panel the layout moves to a new page leaves the tail above on its page; a tail left over the last block of a section is named. Fidelity baselines (Word, LibreOffice on Windows) rewritten: twelve documents stand nearer the page in Word, eight further where the whole border taken out of the space had made up for other errors. --- CHANGELOG.md | 55 +- .../architecture/backend-capability-matrix.md | 4 +- docs/recipes/docx-export.md | 38 +- .../libreoffice-windows-lines.tsv | 1751 +++++++++-------- .../docx-fidelity/libreoffice-windows.tsv | 48 +- .../docx-fidelity/word-windows-lines.tsv | 1667 ++++++++-------- .../resources/docx-fidelity/word-windows.tsv | 48 +- render-docx/README.md | 4 +- .../semantic/docx/DocxSemanticBackend.java | 371 +++- .../docx/DocxContainerSpacingTest.java | 19 +- .../docx/DocxNodeFieldLedgerTest.java | 21 +- .../semantic/docx/DocxPanelHeightTest.java | 26 +- .../semantic/docx/DocxPanelTailTest.java | 540 +++++ .../semantic/docx/DocxRowPaintTest.java | 33 +- 14 files changed, 2731 insertions(+), 1894 deletions(-) create mode 100644 render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelTailTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index fd91acc1b..a0e620104 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,47 @@ follow semantic versioning; release dates are ISO 8601. ### Public API +- **A DOCX export sets what follows a panel where the page sets it, and names what Word sets + lower.** Word sets a panel's content below its whole top border and its margin inside the + table's row, and ends the row its margin and its whole bottom border past the content; the + page strokes each border on the panel's edge. The export took each border whole out of the + space round the panel: a padded card with a gap below it stood what followed half a border + high, and a card with neither stood it the border lower, named for a row's panel only. + - **Half a border reaches past the panel**, and as much of its inner half as the padding + falls short of it. The space round the panel takes that first, the border then standing + where the page strokes it; then the panel's padding, the border then drawn that much inside + the panel's edge and its content where the page sets it; above, then, the room over its + first line. What none of them takes is named: on the panel for its top border, as a row's + was, and on the block that stands lower for its bottom one (`space above`). + - **The height held is the content's.** Word and LibreOffice read a panel's written row height + as its content's, its margins and both borders round it: held a point above its content's + height, an outlined card padded 4pt stood a point taller than the page's. A panel holds the + page's height less its padding, and less what the room over its first line gave its top + border. A shape container, its layers centred in it, holds its outline's height less both + its borders and its margins, which keep inside it, and nothing of them is named; a padded + outlined one was held one border less only. + - **What a panel's content leaves below itself** past where the page ends it — a last line held + to an icon, the border of a card ending the panel — comes out of the room the page leaves + under that content, then out of the panel's padding below, then out of the space under the + panel; what none of them takes is named (`space above`). A card's border ending a row's cell + reaches past the row only by what the row's room under that cell does not hold. + - **The paragraph Word keeps between any two tables** — a tenth of a point, without which + Word merges them — is named on the second where the space between them does not take it + (`space above`), together with a border reaching it. + + Measured in Word 16 and LibreOffice alike on cards with 2pt borders — above, below and all + round — with no padding and with 1 and 4pt of it, with and without space round them, stacked + and in a row's columns, every line stood where the page sets it, or as much lower as the + report names: within 0.15pt in Word and 0.05pt in LibreOffice. In the DOCX fidelity corpus + 25 of the 62 documents change, and the report names 15 more notes: the tenth of a point + between two tables, 14 times, and `ObsidianInvoice`'s totals row, 0.72pt below a border + nothing takes. Twelve documents stand nearer the page in Word — the engineering cover + letter's median line from 1.27pt to 0.13pt — and eight further, `cv-panel`, + `invoice-subscription`, `cv-modern_professional` and `cv-classic_serif` most: there the + whole border taken out of the space had made up for other errors, a heading's baseline left + up to half a point from where Word seats it in an exact line, a spacer of no height written + as a tenth of a point, rounding to the twip inside a card. The fidelity baselines record both. + - **A DOCX export writes a row's fill, outline and side borders, as a panel holding its columns.** A row paints its box as a container does — `RowBuilder.fillColor`, `stroke`, `borders` — and the export wrote its columns as a table with no shading or borders, naming the @@ -23,14 +64,12 @@ follow semantic versioning; release dates are ISO 8601. - **What stands on the row is set on its fill.** A chip, a rule or a translucent panel in one of its columns is flattened against the panel's shading as written, where it was flattened against the page under the row. - - **Borders above and below are named.** Word draws them outside the panel's row, where the - page strokes them on the box's edge: where no space round the row takes them, what follows - stands up to their width lower (`RowNode`, `APPROXIMATED`). Measured, five rows with a 1pt - bottom border one under the other set what follows 5.4pt low in Word and LibreOffice: their - borders' 5pt, and a tenth of a point for each hairline paragraph Word needs between two - tables, as five containers with that border do. A top border wider than the row's padding - stands its columns that much lower too, where the space above does not take it, and the - note says so. + - **Borders above and below reach past its box**, as a panel's do: what of them neither the + space round the row nor its padding takes stands its columns, or what follows, that much + lower, and is named (see the entry above on what follows a panel). Measured, five rows with + a 1pt bottom border and no padding, one under the other, set what follows 5.4pt low in Word + and LibreOffice: their borders' 5pt, and a tenth of a point for each hairline paragraph Word + needs between two tables. - **Still named as `row paint`**, its columns written alone: - composed in a table cell, whose table draws its box as a shape where it frames no text; - in a page zone's line; diff --git a/docs/architecture/backend-capability-matrix.md b/docs/architecture/backend-capability-matrix.md index cb0231a56..c24d35c5d 100644 --- a/docs/architecture/backend-capability-matrix.md +++ b/docs/architecture/backend-capability-matrix.md @@ -70,7 +70,7 @@ Payload records live in `core` under | Inline vector shapes (`ParagraphShapeSpan`) | ✅ `PdfParagraphFragmentRenderHandler` | ⚠️ `PptxParagraphFragmentRenderHandler` + `PptxInlineGeometry` (distinct per-corner radii render with the top-left radius — single-adjust preset) | ⚠️ `DocxSemanticBackend.writeInlinePicture` + `DocxShapePictures` (a transparent PNG drawn by the shared `InlineSvgRasters` from the outline, fill and stroke — every outline kind, each layer centred in the run's box — placed as an inline picture is; the picture takes as far as the stroked ink reaches past the outline — half the stroke on an edge, more at a sharp corner's miter — and a pixel on each side, measured side by side, and is lowered by what it takes below, so no edge is cut and a shape takes that much more room in the line; a list marker that draws a disc is its picture; at the top level of a `hangingIndent(true)` list that does not nest it is followed by a tab to where the layout starts the item's text, the item's lines hanging there, when the picture clears that stop, else by a space) | | Inline SVG (`ParagraphSvgSpan`) | ✅ `PdfParagraphFragmentRenderHandler` + `PdfPathPainter` | ⚠️ `PptxParagraphFragmentRenderHandler` + `PptxInlineGeometry` + `PptxInlineSvgRasterizer` (simple layers stay native; arbitrary clips, exact dash/cap/join styles, and off-viewBox art use a transparent PNG fallback — drawn by the shared `InlineSvgRasters`; gradient paints use their primary colour) | ⚠️ `DocxSemanticBackend.writeInlinePicture` (always the transparent PNG: the same layers the layout resolves, through `InlineSvgLayers`, drawn by the raster the PPTX fallback uses — `InlineSvgRasters`, four pixels a point — and placed as an inline picture is; emoji included, so an emoji is a picture rather than a character, reported `APPROXIMATED`) | | Text an inline icon stands for — copy, search, extraction (`ParagraphSvgSpan.text`, set by `SvgIcon.withText` and on every `EmojiLibrary` emoji) | ✅ `PdfTextLayer` via `PdfRenderEnvironment.writeTextLayer`: one invisible glyph over the icon on the line's baseline, from a Type 3 font of empty glyphs whose `ToUnicode` states each text, a whole ZWJ sequence included; rendering mode 3, so nothing is painted. One font per document, a new one after 255 distinct texts; a text over 256 UTF-16 units is not written. A block icon (`addSvgIcon`, `SvgIcon.node`) writes no text. `ActualText` around the paths was measured to reach none of PDFBox, poppler, pdf.js and MuPDF — it replaces glyphs, and a drawing has none. In a right-to-left line the glyph sits between the words it was written between and states its whole text; reading such a line back, PDFBox reverses the emoji one UTF-16 unit at a time and poppler reverses the code points of a ZWJ sequence or a U+FE0F pair, while pdf.js and MuPDF keep it whole (measured; a reader-side reversal of the glyph's text) | ❌ the icon is drawn and its text is not written | ⚠️ the icon is a picture whose description (`docPr/@descr`) is its text — read by a screen reader, but not a character a reader copies or searches | -| Rectangle shape — fill, stroke, per-corner radii, side borders (`ShapeFragmentPayload`) | ✅ `PdfShapeFragmentRenderHandler` | ⚠️ `PptxShapeFragmentRenderHandler` (distinct per-corner radii render with the top-left radius on all corners — single-adjust `roundRect` preset — until custom geometry lands; uniform radii and side borders exact) | ⚠️ `DocxSemanticBackend.writeContainerChildren` — a `SectionNode` or `ContainerNode` carrying a fill, per-side borders or a uniform stroke is written as a one-cell table, and so is a `RowNode` in the flow that paints its box (`writePaintedRow`, through the same `writePanelPiece`), its columns a table nested in the cell without its padding — not in a band of layers or a stack's measured column, with a padding or margin it cannot hold, composed in a table cell or in a page zone, where it is its columns alone and its paint is reported: the cell's shading is the fill behind everything inside, its borders are the container's at its full height, and its margins are the padding on all four sides, less half of each border, with the table half a border wider on each side, so the text and the border land where the page draws them — in the body, the left margin is the whole padding, the table no wider on that side, and its indent places its text, as Word 16 and LibreOffice on Windows centre a body table's left border on its edge (an older LibreOffice, the Linux CI's, reads the indent as the table's edge and sets the text about a padding right). A panel with less space above it than its top border — such as one opening a table cell — takes what of the border neither that space nor its padding holds from the space above its first line, where that line has some, and where its row holds the page's height that height is less the borders Word draws outside it, since Word starts a cell's content below its top border or its top margin, whichever is wider (LibreOffice, where `MerchantInvoice`'s panel's content sets its height, draws it that border's width shorter). The table takes the width the layout placed the container at, plus a point of editor slack; in a cell, a panel whose left border hangs half its width left of the cell's text gives up what runs past the cell's edge as Word starts it, half that border in — no more than its left side had given its text, the half border the table is wider by and what its left margin gave back of the other half —, since a nested table running past its cell widens the cell, fixed layout or not. A `keepTogether()` panel the layout held on one page is a row that may not split. Panels, rows and tables inside it are tables in its cell; a table cell no style fills is written white, as the page draws it. One deviation: the corner radius is dropped (a cell is rectangular) with one warning per export. A translucent fill is flattened against what Word paints under the panel: the panel or cell around it as written, or on the page the colour the layout paints there (`DocxLayoutMetrics.colourUnder`: the fills drawn before it, at its centre, a page background included and a row's own fill left out, what stands on it being written in the row's panel, on its shading). A translucent border is flattened against the panel's fill where it has one, since a cell's shading and borders are opaque; each is named in the report as `translucency`. An unpainted container is not a table: its paragraphs are indented by every enclosing margin and padding, and its rows and tables get `w:tblInd`. A standalone `ShapeNode` that is only a fill, with no stroke, radius, gradient or transform, and no taller than Word's thickest border (12pt) — an `addDivider` — is a rule, written as a line's is; any other `ShapeNode`, standalone or laid over others, is drawn by `DocxDrawings` as a floating DrawingML shape behind the text, where the layout placed it — `rect`, or `roundRect` with the largest corner radius, in its fill and outline colours with their alpha, each side border a line along its edge; a gradient paint and a transform are not carried, nor are a link, an outline entry or an anchor's bookmark — each named in the shape's report note, as unequal corners are —, and a shape with neither a fill colour nor an outline is dropped and reported. It is anchored in the paragraph whose text it stands beside, placed down from its top, so it moves with that text when the text above is edited; beside no text, in a body paragraph on its page (a table cell's only on a page with no other, reported), where it stays — except a drawing that is all a table cell holds, an icon beside its label (in a row of the flow, a layer stack or shape container that only draws, with no margins, on one page and painting nothing outside its box; in a composed cell, a layer stack of shapes with no margin or padding, the only drawing the cell holds, matched to the table's fragments inside the cell by kind and size), which is anchored in that cell's paragraph, held at its height and placed from its top and the cell's text column, so it moves with its row; a drawing holding a line stays on the page —, and is drawn in front of the text inside a filled panel unless it frames text or a picture there; reported `APPROXIMATED` | +| Rectangle shape — fill, stroke, per-corner radii, side borders (`ShapeFragmentPayload`) | ✅ `PdfShapeFragmentRenderHandler` | ⚠️ `PptxShapeFragmentRenderHandler` (distinct per-corner radii render with the top-left radius on all corners — single-adjust `roundRect` preset — until custom geometry lands; uniform radii and side borders exact) | ⚠️ `DocxSemanticBackend.writeContainerChildren` — a `SectionNode` or `ContainerNode` carrying a fill, per-side borders or a uniform stroke is written as a one-cell table, and so is a `RowNode` in the flow that paints its box (`writePaintedRow`, through the same `writePanelPiece`), its columns a table nested in the cell without its padding — not in a band of layers or a stack's measured column, with a padding or margin it cannot hold, composed in a table cell or in a page zone, where it is its columns alone and its paint is reported: the cell's shading is the fill behind everything inside, its borders are the container's at its full height, and its margins are the padding on all four sides, less half of each border, with the table half a border wider on each side, so the text and the border land where the page draws them — in the body, the left margin is the whole padding, the table no wider on that side, and its indent places its text, as Word 16 and LibreOffice on Windows centre a body table's left border on its edge (an older LibreOffice, the Linux CI's, reads the indent as the table's edge and sets the text about a padding right). Word sets a cell's content its whole top border and its margin inside the row, and ends the row its margin and its whole bottom border past the content, so half of each border — and as much of its inner half as the padding falls short of it — reaches past the panel: the space round it takes that first, then its padding, the border then drawn that much inside the panel's edge, then, above, the room over its first line; what none of them takes is reported (`space above` on the block below, the panel's kind for its top border). What its content leaves below itself past where the page ends it — a last line held to an icon, a card's border ending it — comes out of the room the page leaves under that content and then out of its padding below first, the same way; and the tenth of a point of the paragraph between any two tables, where the space between them does not take it, is reported too. A shape container's borders stay inside its outline. A panel the layout measures holds the page's height less its padding as its row's height, which Word and LibreOffice read as its content's, its margins and borders round it; a shape container holds its outline's, less its borders and margins. The table takes the width the layout placed the container at, plus a point of editor slack; in a cell, a panel whose left border hangs half its width left of the cell's text gives up what runs past the cell's edge as Word starts it, half that border in — no more than its left side had given its text, the half border the table is wider by and what its left margin gave back of the other half —, since a nested table running past its cell widens the cell, fixed layout or not. A `keepTogether()` panel the layout held on one page is a row that may not split. Panels, rows and tables inside it are tables in its cell; a table cell no style fills is written white, as the page draws it. One deviation: the corner radius is dropped (a cell is rectangular) with one warning per export. A translucent fill is flattened against what Word paints under the panel: the panel or cell around it as written, or on the page the colour the layout paints there (`DocxLayoutMetrics.colourUnder`: the fills drawn before it, at its centre, a page background included and a row's own fill left out, what stands on it being written in the row's panel, on its shading). A translucent border is flattened against the panel's fill where it has one, since a cell's shading and borders are opaque; each is named in the report as `translucency`. An unpainted container is not a table: its paragraphs are indented by every enclosing margin and padding, and its rows and tables get `w:tblInd`. A standalone `ShapeNode` that is only a fill, with no stroke, radius, gradient or transform, and no taller than Word's thickest border (12pt) — an `addDivider` — is a rule, written as a line's is; any other `ShapeNode`, standalone or laid over others, is drawn by `DocxDrawings` as a floating DrawingML shape behind the text, where the layout placed it — `rect`, or `roundRect` with the largest corner radius, in its fill and outline colours with their alpha, each side border a line along its edge; a gradient paint and a transform are not carried, nor are a link, an outline entry or an anchor's bookmark — each named in the shape's report note, as unequal corners are —, and a shape with neither a fill colour nor an outline is dropped and reported. It is anchored in the paragraph whose text it stands beside, placed down from its top, so it moves with that text when the text above is edited; beside no text, in a body paragraph on its page (a table cell's only on a page with no other, reported), where it stays — except a drawing that is all a table cell holds, an icon beside its label (in a row of the flow, a layer stack or shape container that only draws, with no margins, on one page and painting nothing outside its box; in a composed cell, a layer stack of shapes with no margin or padding, the only drawing the cell holds, matched to the table's fragments inside the cell by kind and size), which is anchored in that cell's paragraph, held at its height and placed from its top and the cell's text column, so it moves with its row; a drawing holding a line stays on the page —, and is drawn in front of the text inside a filled panel unless it frames text or a picture there; reported `APPROXIMATED` | | Ellipse (`EllipseFragmentPayload`) | ✅ `PdfEllipseFragmentRenderHandler` | ✅ `PptxEllipseFragmentRenderHandler` | ⚠️ `DocxDrawings` — an `ellipse` shape anchored as a rectangle is; a shape container's elliptical outline is drawn the same way, and a picture that fills the container it clips takes the ellipse as its geometry; a transform is not carried, nor a link, an outline entry or an anchor's bookmark (each named in the ellipse's report note), and a shape in a filled panel is drawn in front of the text, over the cell's shading, unless it frames text or a picture; a shape is anchored as a rectangle is — except, as for a rectangle, a drawing that is all a table cell holds — in a row of the flow, a badge alone beside its text — which is anchored in that cell and moves with its row | | Line — dash pattern, line cap (`LineFragmentPayload`) | ✅ `PdfLineFragmentRenderHandler` | ⚠️ `PptxLineFragmentRenderHandler` (numeric dash arrays map to the generic dashed preset; solid lines and caps exact) | ⚠️ `DocxSemanticBackend.writeRule` — a horizontal line with no transform is Word's own rule: an empty paragraph whose bottom border is the stroke (colour, thickness in eighths of a point, clamped to Word's 12pt), its ends as the paragraph's indents and the space above and below the stroke in its box as the paragraph's height and the space owed below it; a dash pattern becomes Word's dashed or dotted border, reported `APPROXIMATED`; a translucent stroke is flattened against the colour the page paints under it, a page background included, reported as `translucency`; the line cap and a link are not carried (both reported, a link as `rule link`; an outline entry on it is reported too). A vertical or slanted line, and a line laid over others in a layer stack, canvas or shape container — a line among the text of a layer stack of one layer excepted, which is a rule —, is drawn by `DocxDrawings` as a `line` shape anchored as a rectangle is — the dash pattern, cap and a transform are not carried, nor a link, an outline entry or an anchor's bookmark (each named in the line's report note); a line in a page zone is dropped and reported | | Polygon (`PolygonFragmentPayload`) | ✅ `PdfPolygonFragmentRenderHandler` | ✅ `PptxPolygonFragmentRenderHandler` + `PptxInlineGeometry` | ⚠️ `DocxDrawings` + `DocxCustomGeometry` — `a:custGeom`, the vertex ring closed, anchored as a rectangle is | @@ -81,7 +81,7 @@ Payload records live in `core` under | Image — STRETCH / CONTAIN / COVER fit (`ImageFragmentPayload`) | ✅ `PdfImageFragmentRenderHandler` | ✅ `PptxImageFragmentRenderHandler` (COVER via the picture source crop) | ✅ `DocxSemanticBackend.writeImage` (the box comes from `NodeDefinitionSupport.resolveImageDimensions`, the same rule layout applies to `width` / `height` / `scale` and the content-width clamp; CONTAIN is embedded at its fitted size, COVER via the picture source crop as in PPTX, and the picture type is read from the bytes; its left margin and padding are not written, and a picture drawn beside its text is fitted to its box with its padding in it — each named in the report) | | Barcode / QR (`BarcodeFragmentPayload`) | ✅ `PdfBarcodeFragmentRenderHandler` (vector: the ZXing bit matrix filled as merged rectangles) | ✅ `PptxBarcodeFragmentRenderHandler` (native freeforms: the same ZXing bit matrix as merged rectangles) | ⚠️ `DocxSemanticBackend.writeBarcode` (a PNG picture of the same ZXing bit matrix through `BarcodeMatrices`, one pixel a cell, in the symbol's two colours with their alpha and at the node's size, its data as the picture's description; it scans, but its data is part of the picture rather than editable, reported `APPROXIMATED`, which also names a link, a transform or its left margin and padding as not carried; an `anchor` is a bookmark on its paragraph; in a page zone it is skipped) | | Table rows — resolved cells, row/col spans, two-pass fill/border paint (`TableRowFragmentPayload`) | ✅ `PdfTableRowFragmentRenderHandler` + row grouping in `PdfFixedLayoutBackend` | ✅ `PptxTableRowFragmentRenderHandler` + row grouping in `PptxFixedLayoutBackend` (positioned rectangles, edge lines, and text frames — never native PPTX tables, which re-lay-out content) | ⚠️ `DocxSemanticBackend.writeTable` (a real Word table on the grid `TableGrid` resolves: `colSpan` maps to `w:gridSpan`, `rowSpan` to `w:vMerge`, and the cascaded `DocumentTableStyle` text style reaches the cell's runs; the cell's fill maps to `w:shd` and its stroke to `w:tcBorders` — the engine's default 1pt black rule where the table states none, not Word's thinner grid — its padding to `w:tcMar`, less above and below the room Word makes for the horizontal rules (half of a rule between two rows, the lower row's, to each; the rules above and below the table whole to their row); a row's cells at the row's smallest top and bottom margins, since both editors give every cell the row's largest, the rest of each cell's padding as space above its first paragraph and below its last, down to the largest margin a cell opening with a table or in a vertical merge keeps; the cascaded `textAnchor` maps to `w:vAlign` on every cell and to `w:jc` on a text cell's paragraph, with the engine's default — the vertical middle, on the left, or on the right for a right-to-left cell — and `DEFAULT` at the bottom left, as the renderer draws it; a composed cell is written by the same writers that write its node anywhere, so one built from an image, a list or a table carries it — a nested table is a real `w:tbl` taking the width of the column it sits in, less its own margins and padding, which is the column's rather than the one the page gives it, since the layout reports a composed cell's content under the owner's path; the paragraph Word requires after a nested table is hidden where it ends its cell holding nothing and no space; a translucent fill is flattened against the colour the page paints under the cell, and a translucent rule against the cell's fill where it has one, since `w:shd` and `w:tcBorders` are opaque, and the table's report note names it (`translucency`); Word re-paginates, so the export states where the layout breaks: every row the layout placed is `w:cantSplit`, `repeatHeader(n)` rows are `w:tblHeader` and keep with the row under them, and a row of blocks is kept whole the same way; the paragraph Word requires after a document's closing table is an ordinary one where the last page has room for two lines below it, so a reader can type below the table, and otherwise a point tall with its mark hidden, so it opens no blank page, reported `APPROXIMATED` since text typed at the end then goes into the table's last cell) | -| Clip region open/close (`ShapeClipBegin/EndPayload`) | ✅ `PdfShapeClipBegin/EndRenderHandler` (CLIP_BOUNDS + CLIP_PATH) | ✅ `PptxClipSafety` + raster fallback in `PptxFixedLayoutBackend` — a provably no-op clip (padded content that cannot be cut) skips the fallback entirely and stays native, editable shapes; a clip that can cut ink renders through the PDF backend into one transparent picture on the clip bounds (pixel-exact, not editable as shapes; run-level link hotspots are not emitted and custom fragment handlers do not apply inside the picture; `Builder.clipRasterFallback(false)` restores unclipped vectors + warning; the raster targets a 2048px long edge, clamped to between native size and 4x, so a region larger than that is rendered at native resolution rather than downscaled — which also means its transient memory grows with the clip instead of stopping at the target (a 3370pt A0-landscape region costs ~45MB while rendering, against ~17MB for anything up to 2048pt); a true vector clip is tracked in [#413](https://github.com/DemchaAV/GraphCompose/issues/413)) | ⚠️ inline fallback + one-time capability warning; the report names a clip that cuts what its layers paint, measured from the layout's fragments by `DocxClipInk` — a clip that cuts nothing (an icon inside its box, a disc's initials, a photo filling its circle) is not named; a picture that fills a container clipped to an ellipse takes the ellipse as its geometry, which both editors crop it to; a badge's glyph — a smaller picture in a painted container that clips it to its outline (`CLIP_PATH`) and holds nothing else but drawing — is drawn by `DocxDrawings` as a floating picture over the outline, where the layout places it, reported `APPROXIMATED` — inside a filled panel the badge and its glyph are drawn in front of the shading; an icon picture beside its text in an unpainted container or a layer stack is drawn the same way; a filled or outlined rectangle or rounded rectangle holding text, composed in a table cell, which has no place in the layout to be drawn at, is written as a panel — a one-cell table in its fill and outline, its corners squared and reported, its row held at least the outline's height less the borders both editors draw outside it where its padding does not hold its top border, and a one-line label the shape centres top to bottom on a line taller than the room Word leaves its content cut alike on both sides to that room, no closer to its letters than three quarters of a point, and seated where the page sets it; the rest of what a composed cell draws (an icon, a tile, a disc) is the table's own drawing and is drawn by `drawCellDrawing` where the layout puts it, anchored as a rectangle is | +| Clip region open/close (`ShapeClipBegin/EndPayload`) | ✅ `PdfShapeClipBegin/EndRenderHandler` (CLIP_BOUNDS + CLIP_PATH) | ✅ `PptxClipSafety` + raster fallback in `PptxFixedLayoutBackend` — a provably no-op clip (padded content that cannot be cut) skips the fallback entirely and stays native, editable shapes; a clip that can cut ink renders through the PDF backend into one transparent picture on the clip bounds (pixel-exact, not editable as shapes; run-level link hotspots are not emitted and custom fragment handlers do not apply inside the picture; `Builder.clipRasterFallback(false)` restores unclipped vectors + warning; the raster targets a 2048px long edge, clamped to between native size and 4x, so a region larger than that is rendered at native resolution rather than downscaled — which also means its transient memory grows with the clip instead of stopping at the target (a 3370pt A0-landscape region costs ~45MB while rendering, against ~17MB for anything up to 2048pt); a true vector clip is tracked in [#413](https://github.com/DemchaAV/GraphCompose/issues/413)) | ⚠️ inline fallback + one-time capability warning; the report names a clip that cuts what its layers paint, measured from the layout's fragments by `DocxClipInk` — a clip that cuts nothing (an icon inside its box, a disc's initials, a photo filling its circle) is not named; a picture that fills a container clipped to an ellipse takes the ellipse as its geometry, which both editors crop it to; a badge's glyph — a smaller picture in a painted container that clips it to its outline (`CLIP_PATH`) and holds nothing else but drawing — is drawn by `DocxDrawings` as a floating picture over the outline, where the layout places it, reported `APPROXIMATED` — inside a filled panel the badge and its glyph are drawn in front of the shading; an icon picture beside its text in an unpainted container or a layer stack is drawn the same way; a filled or outlined rectangle or rounded rectangle holding text, composed in a table cell, which has no place in the layout to be drawn at, is written as a panel — a one-cell table in its fill and outline, its corners squared and reported, its row held at least the outline's height less its borders and margins, which keep inside it, and a one-line label the shape centres top to bottom on a line taller than the room Word leaves its content cut alike on both sides to that room, no closer to its letters than three quarters of a point, and seated where the page sets it; the rest of what a composed cell draws (an icon, a tile, a disc) is the table's own drawing and is drawn by `drawCellDrawing` where the layout puts it, anchored as a rectangle is | | Timeline rail — one logical connector line resolved from marker and entry anchors after layout (`ShapeFragmentPayload` per page) | ✅ `PdfShapeFragmentRenderHandler` — one fragment per page, spliced beneath the markers | ✅ `PptxShapeFragmentRenderHandler` — same payload, same per-page fragments | ⚠️ `DocxDrawings` — the rail is read from the resolved layout's pass fragments and drawn per page as a `line` shape, and the markers as the shapes they are, anchored as a rectangle is: beside an entry's text they move with it when the text above is edited | | Transform open/close — rotate/scale about fragment centre (`TransformBegin/EndPayload`) | ✅ `PdfTransformBegin/EndRenderHandler` | ✅ `PptxTransformBegin/EndRenderHandler` (group shape; rotation and centre-pivot scaling via the exterior/interior frame ratio) | ⚠️ inline fallback + one-time capability warning; a turned shape container is written upright, and the report names its transform — in its drawn outline's note, or on its own where the outline draws nothing | | Anchor markers (`AnchorMarkerPayload`) | ✅ `PdfAnchorMarkerRenderHandler` + `PdfInternalLinkWriter` | ✅ `PptxAnchorMarkerRenderHandler` + `PptxNavigationWriter` (slide-jump hyperlinks resolved after all fragments, so forward references work) | ✅ `DocxSemanticBackend` — an anchor becomes a `w:bookmarkStart` / `w:bookmarkEnd` pair wrapping the paragraph's text, named as Word requires (letters, digits and underscores, starting with a letter, 40 characters); two anchors that clean to one name stay two bookmarks | diff --git a/docs/recipes/docx-export.md b/docs/recipes/docx-export.md index 06261a5d2..b22ecaf41 100644 --- a/docs/recipes/docx-export.md +++ b/docs/recipes/docx-export.md @@ -74,7 +74,7 @@ creation date is real metadata. | Inline chips (`inlineCode(...)`, `inlineChip(...)`, `highlight(...)`) | The chip's fill becomes the run's own `w:shd`, in a paragraph and in a list item alike. Its shape does not travel — see "What a chip keeps and loses" below | | Images | Embedded pictures at the node's declared size. In the flow, the margin and padding above and below are the space round the picture's paragraph; on the left they are not written, and the report names them, as it does a barcode's and a page reference's sides. A picture drawn beside its text is fitted to its box with its padding in it, which the report names too | | Links and anchors | A `linkTarget` becomes a `w:hyperlink` — a relationship for an address, `w:anchor` for one of the document's own anchors — and a run's own link wins over the paragraph's — in a list item as much as in a paragraph. An `anchor(...)` becomes a bookmark wrapping that paragraph's text, named as Word requires; on a section, container, table or image it wraps everything the block wrote, from the start of its first paragraph to the end of its last, so a link to a block lands on its first line. A `bookmark(...)` outline level becomes Word's own `HeadingN` style, which is what puts the paragraph in the Navigation Pane, the outline view and a generated table of contents. The style states the outline level and nothing else, so the paragraph keeps its own formatting. The role comes from what the document declared, never from how big the text is | -| Rows | A one-row table spanning the content width — or only its columns, where fixed columns leave part of the row empty — so editors keep the side-by-side layout. The row's slots become the column grid when they are weights, an even split or fixed columns; fixed columns that add up to less than the row leave the rest of it empty, the last one at its own width and the table no wider than its columns, so its text wraps where the page wraps it; the gap and the row's padding ride in the neighbouring column and come back out as that cell's margin; a cell holds whatever its child is, written as it is anywhere else. The row's `verticalAlign` is every cell's `w:vAlign`, so a child shorter than the row sits at its middle or bottom as on the page — a table of contents' leader on its entry's baseline. The row is kept whole across a page break, as the layout keeps it. A row is held at least as tall as the page makes it inside a painted panel, and anywhere its tallest child is a drawing Word holds nothing of in its cell — a badge beside a heading. A section or other container in any cell — a row's, a table's, a panel's — that pulls its first line up with a negative top edge writes that one-line paragraph as much shorter, its text seated where the page sets it — no more than the room above its letters, as Word draws an exact line's text only inside the line. A row that paints its box — `fillColor`, `stroke`, `borders` — is a panel holding its columns (see "What a panel keeps and loses" below): a table of one cell carrying the fill and borders, its margins the row's padding as a panel's are, and in it the columns as a table of their own, without the padding; a corner radius squares, and is named (`corner radius`), and so are borders above and below, which Word draws outside the panel's row, and a top border its padding does not take, which stands the columns that much lower. A row composed in a table cell, in a page zone's line, in a band of overlapping layers or where a stack's column measures the space round it to its text, with a padding below zero or a column hanging into it, or with a margin below zero above or below it or at a side in a cell, is written as its columns alone, its paint in the report (`row paint`); in the body a row bleeding past the margin is its panel | +| Rows | A one-row table spanning the content width — or only its columns, where fixed columns leave part of the row empty — so editors keep the side-by-side layout. The row's slots become the column grid when they are weights, an even split or fixed columns; fixed columns that add up to less than the row leave the rest of it empty, the last one at its own width and the table no wider than its columns, so its text wraps where the page wraps it; the gap and the row's padding ride in the neighbouring column and come back out as that cell's margin; a cell holds whatever its child is, written as it is anywhere else. The row's `verticalAlign` is every cell's `w:vAlign`, so a child shorter than the row sits at its middle or bottom as on the page — a table of contents' leader on its entry's baseline. The row is kept whole across a page break, as the layout keeps it. A row is held at least as tall as the page makes it inside a painted panel, and anywhere its tallest child is a drawing Word holds nothing of in its cell — a badge beside a heading. A section or other container in any cell — a row's, a table's, a panel's — that pulls its first line up with a negative top edge writes that one-line paragraph as much shorter, its text seated where the page sets it — no more than the room above its letters, as Word draws an exact line's text only inside the line. A row that paints its box — `fillColor`, `stroke`, `borders` — is a panel holding its columns (see "What a panel keeps and loses" below): a table of one cell carrying the fill and borders, its margins the row's padding as a panel's are, and in it the columns as a table of their own, without the padding; a corner radius squares, and is named (`corner radius`), and what of its borders above and below Word draws past its box is taken, or named, as a panel's is. A row composed in a table cell, in a page zone's line, in a band of overlapping layers or where a stack's column measures the space round it to its text, with a padding below zero or a column hanging into it, or with a margin below zero above or below it or at a side in a cell, is written as its columns alone, its paint in the report (`row paint`); in the body a row bleeding past the margin is its panel | | Sections / containers | Children written in order. A timeline with its markers on the rail (`markerOnRail()`) lays each entry's body out in the header row's content column, below the row; the body is written in the flow, indented to that column where the page puts it. A container with a fill, per-side borders or a uniform stroke is a one-cell table carrying them, its padding as the cell's margins, so a card keeps its panel — see "What a panel keeps and loses" below. A `keepTogether()` or `keepWithNext()` block the layout placed on one page stays on one page in Word too (`w:keepLines` + `w:keepNext`, and a row that may not split for a panel). A box with no paint is only its contents, so a `fixedWidth` narrower than the column is not written: its paragraphs and lists run the column's width, as a panel's in a table cell do, and the report names it. Under an alignment wrapper, or as a layer of a band, the box is held in to where the page placed it. A painted section's bleed is not written: its fill and borders stop at its box, and where the page bleeds it — in the flow it lays out page by page, the body and the panels in it — the report names it. A line drawn as a shape holds no keep: its drawing is anchored in a paragraph near it, a page can end between it and the next block, and in that same flow the report names the keep it loses | | Spacers | An empty paragraph a tenth of a point tall, which Word keeps (a shorter spacer stands that tenth); the rest of the spacer's height is the space above the next block, or below this paragraph when a table follows. A spacer in the body the layout moves to a new page with the gap before it, because the gap did not fit at the foot of the page above, holds the space the layout leaves above it there — that gap, and the edges of any containers opening with it — in its line, which Word keeps at the top of a page where it drops the space above. A spacer's own margin and padding are not written, and the report names them — except below the lowest block of a band, or of a layer another resumes after in its column, where the space is measured from the page, the block's own margin and padding included | | Page breaks | Explicit Word page breaks | @@ -519,6 +519,28 @@ How it lands: padding right of the page's. Measured on `ModernInvoice`'s 4pt accent, half of it taken off the margin stood every line in the panel 2pt left of the page's, in Word and LibreOffice alike. +- **Borders above and below.** Word sets a panel's content below its whole top border and its + margin, and ends the row its margin and its whole bottom border past the content; the page + strokes both borders on the panel's edge. So half a border reaches past the panel above and + below, and as much of its inner half as the padding falls short of it. The space round the + panel takes that first, the border then standing where the page strokes it; then the panel's + padding, the border drawn that much inside the panel's edge and the content where the page + sets it; above, then, the room over its first line. What none of them takes stands the + content, or the block below, that much lower, and the report names it: on the panel for its + top border, on the block below for its bottom one (`space above`). A shape container's + borders, its layers centred in it, stay inside its outline. Measured in Word 16 and + LibreOffice alike on 2pt borders with no padding and with 1 and 4pt of it, every line stood + where the page sets it, or as much lower as the report names: within 0.15pt in Word and + 0.05pt in LibreOffice. +- **Height.** Word and LibreOffice read a panel's row's written height as its content's, its + margins and both borders round it, so a panel the layout measures is held to the page's + height less its padding, and a shape container to its outline's, less its borders and margins. +- **What hangs below.** What a panel's content leaves below itself past where the page ends it + — a last line held to an icon, the border of a card ending the panel — comes out of the room + the page leaves under that content, then out of the panel's padding below, then out of the + space under the panel; the rest is named (`space above`). So is the tenth of a point of the + paragraph Word keeps between any two tables, which it would otherwise merge, where the space + between them does not take it. - **Indent.** In the body the table's `w:tblInd` places its cell's text, the padding in, and is written even when it is 0 — a panel bled to the paper's edge by a negative margin its padding takes back. Unwritten, Word 16 puts the table's edge on the margin and the text a @@ -989,17 +1011,9 @@ left or linked are written in the flow as before. A shape beside text in a panel that text's paragraph in the cell and laid out in the cell, placed from the cell's text column and the paragraph's top, which Word and LibreOffice both measure from the paragraph, nested or not; placed from the page's edges instead, Word measured a nested cell's shape from -the outer cell's top. Word draws a panel's top and bottom borders outside the cell's -shading, where the page strokes them on the panel's edge, so the top border comes out of the -space above the panel, and the bottom border out of the space the panel holds below itself -or, past that, out of the space above the paragraph, table or panel that follows. A panel with -less space above it than its top border — such as one opening a table cell — takes what of the -border neither that space nor its padding holds out of the space above its first line inside, -where that line has some, and where its row holds the page's height, that height is less the -borders Word draws outside it: Word starts a cell's content below its top border, or its top -margin where that is wider, and draws both borders outside the row's height. Measured, -`MerchantInvoice`'s payment panel, its height set by its content in LibreOffice, stands that -border's width shorter there. The body's +the outer cell's top. Word sets a panel's content below its whole top border and ends its row past its whole +bottom border, where the page strokes both on the panel's edge; what of them reaches past the +panel's box is taken, or named, as "What a panel keeps and loses" says. The body's shapes stand above the page backgrounds, which LibreOffice stacks together with them. Each of these limits is named in the report: - A transform is not carried: a rotated or scaled shape is drawn upright at its size, and so diff --git a/qa/src/test/resources/docx-fidelity/libreoffice-windows-lines.tsv b/qa/src/test/resources/docx-fidelity/libreoffice-windows-lines.tsv index 11554768b..240a7a361 100644 --- a/qa/src/test/resources/docx-fidelity/libreoffice-windows-lines.tsv +++ b/qa/src/test/resources/docx-fidelity/libreoffice-windows-lines.tsv @@ -52,46 +52,46 @@ cv-blue_banner 0:88b226d51fe1 0.36 0.10 pngdiffing,side-by-sidelayout,ba cv-blue_banner 0:339245d63103 0.42 0.10 layoutlint(java21,javaparser,spo cv-blue_banner 0:8c87b84946f3 0.72 0.10 beforetheyshiptoproduction. cv-boxed_sections 0:8f1010120ed6 0.46 2.20 jordanrivera -cv-boxed_sections 0:8d7a2cca3060 -0.12 0.22 +442055551000|jordan.rivera@exam -cv-boxed_sections 0:b944906ed84c -0.42 1.49 professionalsummary -cv-boxed_sections 0:80cc87fdc4c4 -0.75 0.10 platformengineerwith10+yearsbuil -cv-boxed_sections 0:bddc0bd093ce -0.75 0.10 systems.specialisedinhigh-throug -cv-boxed_sections 0:95a43d7b3df0 -0.74 0.10 snapshot-testedlibrariesthatscal -cv-boxed_sections 0:5f94c50dc5bf -0.43 1.32 technicalskills -cv-boxed_sections 0:eea537278f83 -0.46 0.10 •languages:java21,kotlin,groovy, -cv-boxed_sections 0:9c2cd7231a53 -0.45 0.10 •document&print:pdfbox,apachepoi -cv-boxed_sections 0:7bf8639ec5d3 -0.45 0.10 •layoutengines:customdsldesign,s -cv-boxed_sections 0:8e66776d28d7 -0.44 0.10 •build&infrastructure:maven,grad -cv-boxed_sections 0:1ed4fc7d7768 -0.44 0.10 •testing:junit5,assertj,pdfbox-b -cv-boxed_sections 0:26671c309eb9 -0.43 0.10 •distribution:mavencentral,sonat -cv-boxed_sections 0:68bf0109c6f8 -0.42 1.23 education -cv-boxed_sections 0:0ad1957d6bab -0.42 0.10 msccomputerscience -cv-boxed_sections 0:3fa772117260 -0.46 -0.76 2019-2021 -cv-boxed_sections 0:47ce0218bbea -0.43 0.10 universityofmanchester -cv-boxed_sections 0:2ffe115b06e5 -0.42 0.10 distinction.thesis:composablelay -cv-boxed_sections 0:b6749d0b616b -0.39 0.10 bscsoftwareengineering -cv-boxed_sections 0:30f9262640a0 -0.42 -0.76 2015-2019 -cv-boxed_sections 0:89ad9656f393 -0.40 0.10 imperialcollegelondon -cv-boxed_sections 0:baa173b4a82e -0.38 0.10 first-classhonours.specialisatio -cv-boxed_sections 0:6d3d5673c39f -0.35 0.10 oraclejavacertification -cv-boxed_sections 0:d40b22f00acb -0.39 -0.76 2023-2024 -cv-boxed_sections 0:2669e1f6d55c -0.36 0.10 professionaltrack -cv-boxed_sections 0:3857373829c1 -0.35 0.10 java17platformdeep-dive:records, -cv-boxed_sections 0:2577c0f557b2 -0.33 1.18 projects -cv-boxed_sections 0:b2b029995203 -0.36 0.10 •graphcompose(java21,pdfbox,mave -cv-boxed_sections 0:67593a76ef70 -0.66 0.11 declarativejavapdflayoutengine.s -cv-boxed_sections 0:b9292cbd1454 -0.65 0.11 pipelinesforhiringtoolsandbillin -cv-boxed_sections 0:1b50bb81df5a -0.35 0.10 •templatestudio(kotlin,composede -cv-boxed_sections 0:836e76daecbf -0.34 0.11 internaltoolforevaluatingcv,prop -cv-boxed_sections 0:25cdca2beb8b -0.34 0.10 •layoutlint(java21,javaparser,sp -cv-boxed_sections 0:7488006d7864 -0.63 0.11 staticanalyserthatflagsfragileau -cv-boxed_sections 0:c4d0c415b4f8 -0.63 0.11 production. -cv-boxed_sections 0:fb1927f88597 -0.32 0.10 •chromeforge(java,graphcompose,p -cv-boxed_sections 0:e7e62230eb1f -0.32 0.11 editorial-magazinedocumenttoolki -cv-boxed_sections 0:c2f296ef30a3 -0.30 1.51 professionalexperience -cv-boxed_sections 0:a76f47480818 -0.31 0.10 seniorplatformengineer -cv-boxed_sections 0:060300b18051 -0.34 0.01 2024-present -cv-boxed_sections 0:f890faef907f -0.32 0.10 northwindsystems +cv-boxed_sections 0:8d7a2cca3060 0.23 0.22 +442055551000|jordan.rivera@exam +cv-boxed_sections 0:b944906ed84c 0.28 1.49 professionalsummary +cv-boxed_sections 0:80cc87fdc4c4 -0.05 0.10 platformengineerwith10+yearsbuil +cv-boxed_sections 0:bddc0bd093ce -0.05 0.10 systems.specialisedinhigh-throug +cv-boxed_sections 0:95a43d7b3df0 -0.04 0.10 snapshot-testedlibrariesthatscal +cv-boxed_sections 0:5f94c50dc5bf 0.27 1.32 technicalskills +cv-boxed_sections 0:eea537278f83 0.24 0.10 •languages:java21,kotlin,groovy, +cv-boxed_sections 0:9c2cd7231a53 0.25 0.10 •document&print:pdfbox,apachepoi +cv-boxed_sections 0:7bf8639ec5d3 0.25 0.10 •layoutengines:customdsldesign,s +cv-boxed_sections 0:8e66776d28d7 0.26 0.10 •build&infrastructure:maven,grad +cv-boxed_sections 0:1ed4fc7d7768 0.26 0.10 •testing:junit5,assertj,pdfbox-b +cv-boxed_sections 0:26671c309eb9 0.27 0.10 •distribution:mavencentral,sonat +cv-boxed_sections 0:68bf0109c6f8 0.28 1.23 education +cv-boxed_sections 0:0ad1957d6bab 0.28 0.10 msccomputerscience +cv-boxed_sections 0:3fa772117260 0.24 -0.76 2019-2021 +cv-boxed_sections 0:47ce0218bbea 0.27 0.10 universityofmanchester +cv-boxed_sections 0:2ffe115b06e5 0.28 0.10 distinction.thesis:composablelay +cv-boxed_sections 0:b6749d0b616b 0.31 0.10 bscsoftwareengineering +cv-boxed_sections 0:30f9262640a0 0.28 -0.76 2015-2019 +cv-boxed_sections 0:89ad9656f393 0.30 0.10 imperialcollegelondon +cv-boxed_sections 0:baa173b4a82e 0.32 0.10 first-classhonours.specialisatio +cv-boxed_sections 0:6d3d5673c39f 0.35 0.10 oraclejavacertification +cv-boxed_sections 0:d40b22f00acb 0.31 -0.76 2023-2024 +cv-boxed_sections 0:2669e1f6d55c 0.34 0.10 professionaltrack +cv-boxed_sections 0:3857373829c1 0.35 0.10 java17platformdeep-dive:records, +cv-boxed_sections 0:2577c0f557b2 0.37 1.18 projects +cv-boxed_sections 0:b2b029995203 0.34 0.10 •graphcompose(java21,pdfbox,mave +cv-boxed_sections 0:67593a76ef70 0.04 0.11 declarativejavapdflayoutengine.s +cv-boxed_sections 0:b9292cbd1454 0.05 0.11 pipelinesforhiringtoolsandbillin +cv-boxed_sections 0:1b50bb81df5a 0.35 0.10 •templatestudio(kotlin,composede +cv-boxed_sections 0:836e76daecbf 0.36 0.11 internaltoolforevaluatingcv,prop +cv-boxed_sections 0:25cdca2beb8b 0.36 0.10 •layoutlint(java21,javaparser,sp +cv-boxed_sections 0:7488006d7864 0.07 0.11 staticanalyserthatflagsfragileau +cv-boxed_sections 0:c4d0c415b4f8 0.07 0.11 production. +cv-boxed_sections 0:fb1927f88597 0.38 0.10 •chromeforge(java,graphcompose,p +cv-boxed_sections 0:e7e62230eb1f 0.38 0.11 editorial-magazinedocumenttoolki +cv-boxed_sections 0:c2f296ef30a3 0.40 1.51 professionalexperience +cv-boxed_sections 0:a76f47480818 0.39 0.10 seniorplatformengineer +cv-boxed_sections 0:060300b18051 0.36 0.01 2024-present +cv-boxed_sections 0:f890faef907f 0.38 0.10 northwindsystems cv-boxed_sections 1:49faf14f1f56 -0.13 0.10 ledthereusabledocument-generatio cv-boxed_sections 1:6bd3f168e89e -0.13 0.10 maintenancetimeby70%byretiringpe cv-boxed_sections 1:daf65306b3b6 0.20 0.10 softwareengineer @@ -174,123 +174,123 @@ cv-charcoal_gold 0:92966f349443 -0.01 0.15 london,unitedkingdom cv-charcoal_gold 0:42535367bd3c -0.01 0.16 anastasiasmith.com cv-charcoal_gold 0:d5d2c85de2b9 -0.01 0.16 linkedin.com/in/anastasiasmith cv-charcoal_gold 0:32c1cf49a2fe -0.23 -0.70 skills -cv-charcoal_gold 0:340455fbac25 -0.11 0.10 projectmanagement -cv-charcoal_gold 0:03cd52ebdc67 -0.11 0.10 budgeting&forecasting -cv-charcoal_gold 0:115925c1b96b -0.11 0.10 stakeholdercommunication -cv-charcoal_gold 0:4e321f38b222 -0.11 0.10 riskmanagement -cv-charcoal_gold 0:2f594f65f16c -0.11 0.10 dataanalysis -cv-charcoal_gold 0:b08c44dac044 -0.11 0.10 processimprovement -cv-charcoal_gold 0:c7b5692b2d27 -0.11 0.10 microsoftexcel -cv-charcoal_gold 0:2e2c6b2f5ad9 -0.11 0.10 powerbi -cv-charcoal_gold 0:f73b1d7d3bc6 -0.11 0.10 jira/confluence -cv-charcoal_gold 0:b011cfad056f -0.11 0.10 agilemethodologies -cv-charcoal_gold 0:6cb574fa10b6 -0.13 -0.70 languages -cv-charcoal_gold 0:b6234d2ea0d6 -0.04 0.10 english -cv-charcoal_gold 0:bef32d2c315a -0.04 0.08 native -cv-charcoal_gold 0:bef32d2c315a#1 -0.04 0.08 native -cv-charcoal_gold 0:aa304b5d1d72 -0.04 0.10 russian -cv-charcoal_gold 0:21bb36ad0638 -0.04 0.10 french -cv-charcoal_gold 0:23ed645595d6 -0.04 0.08 b2–upperintermediate -cv-charcoal_gold 0:28561c6b68fc -0.04 0.10 german -cv-charcoal_gold 0:3cb3c2736bad -0.04 0.08 a2–basic -cv-charcoal_gold 0:68bf0109c6f8 -0.03 -0.70 education -cv-charcoal_gold 0:48f12eb2ea0d -0.01 0.56 mscprojectmanagement -cv-charcoal_gold 0:ede0c8c47a1f -0.01 0.10 universitycollegelondon -cv-charcoal_gold 0:fc3f0389b9de -0.01 0.10 2018–2019 -cv-charcoal_gold 0:66cb4ff79ee1 -0.02 0.56 bscbusinessadministration -cv-charcoal_gold 0:8826393fc0f0 -0.02 0.10 king'scollegelondon -cv-charcoal_gold 0:c7d18ae8c50d -0.02 0.10 2014–2017 +cv-charcoal_gold 0:340455fbac25 -0.21 0.10 projectmanagement +cv-charcoal_gold 0:03cd52ebdc67 -0.21 0.10 budgeting&forecasting +cv-charcoal_gold 0:115925c1b96b -0.21 0.10 stakeholdercommunication +cv-charcoal_gold 0:4e321f38b222 -0.21 0.10 riskmanagement +cv-charcoal_gold 0:2f594f65f16c -0.21 0.10 dataanalysis +cv-charcoal_gold 0:b08c44dac044 -0.21 0.10 processimprovement +cv-charcoal_gold 0:c7b5692b2d27 -0.21 0.10 microsoftexcel +cv-charcoal_gold 0:2e2c6b2f5ad9 -0.21 0.10 powerbi +cv-charcoal_gold 0:f73b1d7d3bc6 -0.21 0.10 jira/confluence +cv-charcoal_gold 0:b011cfad056f -0.21 0.10 agilemethodologies +cv-charcoal_gold 0:6cb574fa10b6 -0.23 -0.70 languages +cv-charcoal_gold 0:b6234d2ea0d6 -0.24 0.10 english +cv-charcoal_gold 0:bef32d2c315a -0.24 0.08 native +cv-charcoal_gold 0:bef32d2c315a#1 -0.24 0.08 native +cv-charcoal_gold 0:aa304b5d1d72 -0.24 0.10 russian +cv-charcoal_gold 0:21bb36ad0638 -0.24 0.10 french +cv-charcoal_gold 0:23ed645595d6 -0.24 0.08 b2–upperintermediate +cv-charcoal_gold 0:28561c6b68fc -0.24 0.10 german +cv-charcoal_gold 0:3cb3c2736bad -0.24 0.08 a2–basic +cv-charcoal_gold 0:68bf0109c6f8 -0.23 -0.70 education +cv-charcoal_gold 0:48f12eb2ea0d -0.21 0.56 mscprojectmanagement +cv-charcoal_gold 0:ede0c8c47a1f -0.21 0.10 universitycollegelondon +cv-charcoal_gold 0:fc3f0389b9de -0.21 0.10 2018–2019 +cv-charcoal_gold 0:66cb4ff79ee1 -0.22 0.56 bscbusinessadministration +cv-charcoal_gold 0:8826393fc0f0 -0.22 0.10 king'scollegelondon +cv-charcoal_gold 0:c7d18ae8c50d -0.22 0.10 2014–2017 cv-charcoal_gold 0:3acba0d7b5dc -0.34 0.09 projectmanager -cv-charcoal_gold 0:3acba0d7b5dc#1 -0.09 0.06 projectmanager +cv-charcoal_gold 0:3acba0d7b5dc#1 -0.19 0.06 projectmanager cv-charcoal_gold 0:f54e0195601a 0.06 0.09 results-drivenprojectmanagerwith cv-charcoal_gold 0:7a0497cef9c6 0.06 0.09 teamsanddeliveringcomplexproject cv-charcoal_gold 0:c38f1902ece8 0.29 0.09 skilledinagileandwaterfallmethod cv-charcoal_gold 0:ca94787c6c7a -0.41 0.09 management.passionateaboutdrivin cv-charcoal_gold 0:53e5e7c5a884 -0.31 -0.71 experience -cv-charcoal_gold 0:086c0e036e67 -0.15 0.09 2021–present -cv-charcoal_gold 0:eddc2d311872 -0.21 0.06 seniorprojectmanager -cv-charcoal_gold 0:243953e20dc4 -0.11 0.06 digitalsolutionsltd·london,uk -cv-charcoal_gold 0:7fde5861c84b -0.04 0.06 •managecross-functionalteamsofup -cv-charcoal_gold 0:80c76af1fe2a -0.02 0.06 •implementagilepracticesthatimpr -cv-charcoal_gold 0:b6bb33b79f44 0.00 0.06 •buildstrongclientrelationshipsa -cv-charcoal_gold 0:6c39082d9294 -0.03 0.09 2019–2021 -cv-charcoal_gold 0:46df57ef8321 0.01 0.06 innovatechsystems·london,uk -cv-charcoal_gold 0:271b01626043 0.04 0.06 •delivered12+projectsacrossitand -cv-charcoal_gold 0:77dd7c2ad6ae 0.06 0.06 •monitoredbudgets,timelines,andr -cv-charcoal_gold 0:bf8278cd4edc 0.08 0.06 •identifiedrisksandimplementedmi -cv-charcoal_gold 0:2773f92777d7 0.10 0.06 •achieved98%on-timeprojectdelive -cv-charcoal_gold 0:ad564a6ee91d 0.07 0.09 2017–2019 -cv-charcoal_gold 0:e085ad3a0d32 0.01 0.06 projectcoordinator -cv-charcoal_gold 0:6ac382583801 0.11 0.06 globalbusinessservices·london,uk -cv-charcoal_gold 0:77aec5bb6b7f 0.14 0.06 •supportedprojectmanagersinplann -cv-charcoal_gold 0:38dafe4a1765 0.16 0.06 •preparedreports,dashboards,andd -cv-charcoal_gold 0:5c95a9041b72 0.18 0.06 •coordinatedmeetingsandtrackedac -cv-charcoal_gold 0:f0d87e2131e2 0.20 0.06 •improvedinternalprocessesandpro -cv-charcoal_gold 0:e831beb04c00 0.11 0.14 certifications -cv-charcoal_gold 0:93a7ba535da0 0.27 0.10 pmp®certification -cv-charcoal_gold 0:0f9f6d10bfa3 0.31 0.10 projectmanagementinstitute -cv-charcoal_gold 0:73a2af8864fc 0.33 0.10 2020 -cv-charcoal_gold 0:73a2af8864fc#1 0.39 0.00 2020 -cv-charcoal_gold 0:043092900ed5 0.30 0.10 prince2®foundation -cv-charcoal_gold 0:544a764703d6 0.34 0.10 axelos -cv-charcoal_gold 0:023e33504ab9 0.36 0.10 2019 -cv-charcoal_gold 0:023e33504ab9#1 0.39 0.10 2019 -cv-charcoal_gold 0:83cd2e790f6a 0.33 0.10 agilepm®foundation -cv-charcoal_gold 0:0005e5872534 0.37 0.10 apmginternational -cv-charcoal_gold 0:6ee18b42fbf1 0.11 0.09 achievements -cv-charcoal_gold 0:3f06e4a3eb33 0.27 0.00 excellenceindeliveryaward -cv-charcoal_gold 0:0c373352626d 0.31 0.00 digitalsolutionsltd -cv-charcoal_gold 0:d398b29d3dbb 0.33 0.00 2023 -cv-charcoal_gold 0:92cb97e6b786 0.30 0.00 processimprovementinitiative -cv-charcoal_gold 0:6517b58450f7 0.34 0.00 increasedefficiencyby30% -cv-charcoal_gold 0:b1ab1e892617 0.36 0.00 2022 -cv-charcoal_gold 0:c2f5106fbd5a 0.33 0.00 topperformer -cv-charcoal_gold 0:058521fbf0d1 0.37 0.00 innovatechsystems -cv-charcoal_gold 0:3def82282260 0.30 -0.71 technicaltools -cv-charcoal_gold 0:eb04bd42c7fb 0.36 -0.94 microsoft365|jira|confluence|asa +cv-charcoal_gold 0:086c0e036e67 -0.25 0.09 2021–present +cv-charcoal_gold 0:eddc2d311872 -0.31 0.06 seniorprojectmanager +cv-charcoal_gold 0:243953e20dc4 -0.21 0.06 digitalsolutionsltd·london,uk +cv-charcoal_gold 0:7fde5861c84b -0.14 0.06 •managecross-functionalteamsofup +cv-charcoal_gold 0:80c76af1fe2a -0.12 0.06 •implementagilepracticesthatimpr +cv-charcoal_gold 0:b6bb33b79f44 -0.10 0.06 •buildstrongclientrelationshipsa +cv-charcoal_gold 0:6c39082d9294 -0.13 0.09 2019–2021 +cv-charcoal_gold 0:46df57ef8321 -0.09 0.06 innovatechsystems·london,uk +cv-charcoal_gold 0:271b01626043 -0.06 0.06 •delivered12+projectsacrossitand +cv-charcoal_gold 0:77dd7c2ad6ae -0.04 0.06 •monitoredbudgets,timelines,andr +cv-charcoal_gold 0:bf8278cd4edc -0.02 0.06 •identifiedrisksandimplementedmi +cv-charcoal_gold 0:2773f92777d7 0.00 0.06 •achieved98%on-timeprojectdelive +cv-charcoal_gold 0:ad564a6ee91d -0.03 0.09 2017–2019 +cv-charcoal_gold 0:e085ad3a0d32 -0.09 0.06 projectcoordinator +cv-charcoal_gold 0:6ac382583801 0.01 0.06 globalbusinessservices·london,uk +cv-charcoal_gold 0:77aec5bb6b7f 0.04 0.06 •supportedprojectmanagersinplann +cv-charcoal_gold 0:38dafe4a1765 0.06 0.06 •preparedreports,dashboards,andd +cv-charcoal_gold 0:5c95a9041b72 0.08 0.06 •coordinatedmeetingsandtrackedac +cv-charcoal_gold 0:f0d87e2131e2 0.10 0.06 •improvedinternalprocessesandpro +cv-charcoal_gold 0:e831beb04c00 0.01 0.14 certifications +cv-charcoal_gold 0:93a7ba535da0 0.07 0.10 pmp®certification +cv-charcoal_gold 0:0f9f6d10bfa3 0.11 0.10 projectmanagementinstitute +cv-charcoal_gold 0:73a2af8864fc 0.13 0.10 2020 +cv-charcoal_gold 0:73a2af8864fc#1 0.19 0.00 2020 +cv-charcoal_gold 0:043092900ed5 0.10 0.10 prince2®foundation +cv-charcoal_gold 0:544a764703d6 0.14 0.10 axelos +cv-charcoal_gold 0:023e33504ab9 0.16 0.10 2019 +cv-charcoal_gold 0:023e33504ab9#1 0.19 0.10 2019 +cv-charcoal_gold 0:83cd2e790f6a 0.13 0.10 agilepm®foundation +cv-charcoal_gold 0:0005e5872534 0.17 0.10 apmginternational +cv-charcoal_gold 0:6ee18b42fbf1 0.01 0.09 achievements +cv-charcoal_gold 0:3f06e4a3eb33 0.07 0.00 excellenceindeliveryaward +cv-charcoal_gold 0:0c373352626d 0.11 0.00 digitalsolutionsltd +cv-charcoal_gold 0:d398b29d3dbb 0.13 0.00 2023 +cv-charcoal_gold 0:92cb97e6b786 0.10 0.00 processimprovementinitiative +cv-charcoal_gold 0:6517b58450f7 0.14 0.00 increasedefficiencyby30% +cv-charcoal_gold 0:b1ab1e892617 0.16 0.00 2022 +cv-charcoal_gold 0:c2f5106fbd5a 0.13 0.00 topperformer +cv-charcoal_gold 0:058521fbf0d1 0.17 0.00 innovatechsystems +cv-charcoal_gold 0:3def82282260 0.10 -0.71 technicaltools +cv-charcoal_gold 0:eb04bd42c7fb 0.16 -0.94 microsoft365|jira|confluence|asa cv-classic_serif 0:8f1010120ed6 -0.15 2.65 jordanrivera cv-classic_serif 0:8d7a2cca3060 0.19 -0.42 +442055551000|jordan.rivera@exam cv-classic_serif 0:3c69d6bb4892 0.24 2.27 professionalprofile -cv-classic_serif 0:32c1cf49a2fe 0.14 0.10 skills -cv-classic_serif 0:873a24d153c8 0.11 0.10 languages:java21,kotlin,groovy,p -cv-classic_serif 0:05e907ef2b18 0.09 0.10 document&print:pdfbox,apachepoi( -cv-classic_serif 0:76656a8a6621 0.06 0.10 layoutengines:customdsldesign,se -cv-classic_serif 0:1cd141fef347 0.04 0.10 build&infrastructure:maven,gradl -cv-classic_serif 0:181ddda7f959 0.01 0.10 testing:junit5,assertj,pdfbox-ba -cv-classic_serif 0:c40c656d9558 -0.01 0.10 distribution:mavencentral,sonaty -cv-classic_serif 0:53e5e7c5a884 0.00 0.10 experience -cv-classic_serif 0:a76f47480818 0.01 0.10 seniorplatformengineer -cv-classic_serif 0:060300b18051 -0.02 0.31 2024-present -cv-classic_serif 0:f890faef907f -0.01 0.10 northwindsystems -cv-classic_serif 0:49faf14f1f56 -0.24 0.10 ledthereusabledocument-generatio -cv-classic_serif 0:6bd3f168e89e -0.25 0.10 maintenancetimeby70%byretiringpe -cv-classic_serif 0:daf65306b3b6 0.03 0.10 softwareengineer -cv-classic_serif 0:e7cc1822c6dc 0.00 1.12 2021-2024 -cv-classic_serif 0:998c1a985022 0.01 0.10 brightleaflabs -cv-classic_serif 0:e55664011cda -0.22 0.10 builtbackendservicesandproductio -cv-classic_serif 0:e80236b6d2b1 -0.23 0.10 itexttoacustomlayoutengine,elimi -cv-classic_serif 0:41bb54fbae8d 0.04 0.10 backendengineer -cv-classic_serif 0:3fa772117260 0.01 1.12 2019-2021 -cv-classic_serif 0:3fa772117260#1 0.03 1.12 2019-2021 -cv-classic_serif 0:ef148f221e31 0.02 0.10 helixprintco -cv-classic_serif 0:9d31a6bfbc69 -0.21 0.10 maintainedahigh-volumeinvoice-pr -cv-classic_serif 0:03af8a628309 -0.22 0.10 change. -cv-classic_serif 0:2577c0f557b2 0.05 0.10 projects -cv-classic_serif 0:0f2c67872251 0.06 0.10 graphcompose(java21,pdfbox,maven -cv-classic_serif 0:67593a76ef70 -0.21 0.10 declarativejavapdflayoutengine.s -cv-classic_serif 0:b9292cbd1454 -0.22 0.10 pipelinesforhiringtoolsandbillin -cv-classic_serif 0:d73d02174dc9 0.05 0.10 templatestudio(kotlin,composedes -cv-classic_serif 0:836e76daecbf 0.03 0.10 internaltoolforevaluatingcv,prop -cv-classic_serif 0:542ec793b5b1 0.05 0.10 layoutlint(java21,javaparser,spo -cv-classic_serif 0:dc31b6a18325 0.03 0.10 staticanalyserthatflagsfragileau -cv-classic_serif 0:ee180ea1e0a5 0.05 0.10 chromeforge(java,graphcompose,pa -cv-classic_serif 0:e7e62230eb1f 0.03 0.10 editorial-magazinedocumenttoolki -cv-classic_serif 0:68bf0109c6f8 0.05 0.10 education -cv-classic_serif 0:0ad1957d6bab 0.06 0.10 msccomputerscience -cv-classic_serif 0:47ce0218bbea 0.04 0.10 universityofmanchester -cv-classic_serif 0:2ffe115b06e5 0.06 0.10 distinction.thesis:composablelay -cv-classic_serif 0:b6749d0b616b 0.08 0.10 bscsoftwareengineering -cv-classic_serif 0:30f9262640a0 0.05 1.12 2015-2019 +cv-classic_serif 0:32c1cf49a2fe 0.39 0.10 skills +cv-classic_serif 0:873a24d153c8 0.36 0.10 languages:java21,kotlin,groovy,p +cv-classic_serif 0:05e907ef2b18 0.34 0.10 document&print:pdfbox,apachepoi( +cv-classic_serif 0:76656a8a6621 0.31 0.10 layoutengines:customdsldesign,se +cv-classic_serif 0:1cd141fef347 0.29 0.10 build&infrastructure:maven,gradl +cv-classic_serif 0:181ddda7f959 0.26 0.10 testing:junit5,assertj,pdfbox-ba +cv-classic_serif 0:c40c656d9558 0.24 0.10 distribution:mavencentral,sonaty +cv-classic_serif 0:53e5e7c5a884 0.25 0.10 experience +cv-classic_serif 0:a76f47480818 0.26 0.10 seniorplatformengineer +cv-classic_serif 0:060300b18051 0.23 0.31 2024-present +cv-classic_serif 0:f890faef907f 0.24 0.10 northwindsystems +cv-classic_serif 0:49faf14f1f56 0.01 0.10 ledthereusabledocument-generatio +cv-classic_serif 0:6bd3f168e89e 0.00 0.10 maintenancetimeby70%byretiringpe +cv-classic_serif 0:daf65306b3b6 0.28 0.10 softwareengineer +cv-classic_serif 0:e7cc1822c6dc 0.25 1.12 2021-2024 +cv-classic_serif 0:998c1a985022 0.26 0.10 brightleaflabs +cv-classic_serif 0:e55664011cda 0.03 0.10 builtbackendservicesandproductio +cv-classic_serif 0:e80236b6d2b1 0.02 0.10 itexttoacustomlayoutengine,elimi +cv-classic_serif 0:41bb54fbae8d 0.29 0.10 backendengineer +cv-classic_serif 0:3fa772117260 0.26 1.12 2019-2021 +cv-classic_serif 0:3fa772117260#1 0.28 1.12 2019-2021 +cv-classic_serif 0:ef148f221e31 0.27 0.10 helixprintco +cv-classic_serif 0:9d31a6bfbc69 0.04 0.10 maintainedahigh-volumeinvoice-pr +cv-classic_serif 0:03af8a628309 0.03 0.10 change. +cv-classic_serif 0:2577c0f557b2 0.30 0.10 projects +cv-classic_serif 0:0f2c67872251 0.31 0.10 graphcompose(java21,pdfbox,maven +cv-classic_serif 0:67593a76ef70 0.04 0.10 declarativejavapdflayoutengine.s +cv-classic_serif 0:b9292cbd1454 0.03 0.10 pipelinesforhiringtoolsandbillin +cv-classic_serif 0:d73d02174dc9 0.30 0.10 templatestudio(kotlin,composedes +cv-classic_serif 0:836e76daecbf 0.28 0.10 internaltoolforevaluatingcv,prop +cv-classic_serif 0:542ec793b5b1 0.30 0.10 layoutlint(java21,javaparser,spo +cv-classic_serif 0:dc31b6a18325 0.28 0.10 staticanalyserthatflagsfragileau +cv-classic_serif 0:ee180ea1e0a5 0.30 0.10 chromeforge(java,graphcompose,pa +cv-classic_serif 0:e7e62230eb1f 0.28 0.10 editorial-magazinedocumenttoolki +cv-classic_serif 0:68bf0109c6f8 0.30 0.10 education +cv-classic_serif 0:0ad1957d6bab 0.31 0.10 msccomputerscience +cv-classic_serif 0:47ce0218bbea 0.29 0.10 universityofmanchester +cv-classic_serif 0:2ffe115b06e5 0.31 0.10 distinction.thesis:composablelay +cv-classic_serif 0:b6749d0b616b 0.33 0.10 bscsoftwareengineering +cv-classic_serif 0:30f9262640a0 0.30 1.12 2015-2019 cv-classic_serif 1:89ad9656f393 0.16 0.10 imperialcollegelondon cv-classic_serif 1:baa173b4a82e 0.18 0.10 first-classhonours.specialisatio cv-classic_serif 1:6d3d5673c39f 0.20 0.10 oraclejavacertification @@ -332,34 +332,34 @@ cv-compact_mono 0:8051a4b5e34f 0.84 0.10 opensource:maintainerofgraphcomp cv-compact_mono 0:08c2e869a75b 0.85 0.10 regularcontributortopdfboxissuet cv-compact_mono 0:12dcd1343975 0.86 0.10 speaking:jvmsummit2024,devoxxuk2 cv-compact_mono 0:3aea7f90f8ed 0.87 0.10 —bothondeclarativedocumentlayout -cv-compact_mono 0:1900eab6c028 0.44 0.09 profile -cv-compact_mono 0:3828b9718a0d -0.15 0.09 platformengineerwith10+yearsbuil -cv-compact_mono 0:f6b5e93ccadd -0.14 0.09 engines,anddeveloper-facingtempl -cv-compact_mono 0:927ef106776a -0.13 0.09 semanticauthoringdsls,andturning -cv-compact_mono 0:330fcb75ed52 -0.12 0.09 librariesthatscale. -cv-compact_mono 0:53e5e7c5a884 0.16 0.09 experience -cv-compact_mono 0:c9efb118bfda -0.19 0.09 seniorplatformengineer,northwind -cv-compact_mono 0:64c4b52dceb1 -0.39 0.09 ledthereusabledocument-generatio -cv-compact_mono 0:1f193cd1d987 -0.37 0.09 productteams.reducedtemplatemain -cv-compact_mono 0:9ccc3e904e5a -0.35 0.09 favourofonecanonicalengine. -cv-compact_mono 0:e21e4e47835a -0.14 0.09 softwareengineer,brightleaflabs| -cv-compact_mono 0:0cdd48f05f9d -0.34 0.09 builtbackendservicesandproductio -cv-compact_mono 0:e48f1e2c853d -0.32 0.09 permonth.drovethemigrationfromit -cv-compact_mono 0:b78a9a72ca9a -0.30 0.09 andcuttingp99renderlatencyfrom1. -cv-compact_mono 0:9f5d87c00954 -0.09 0.09 backendengineer,helixprintco|201 -cv-compact_mono 0:a485c37fe7ea -0.29 0.09 maintainedahigh-volumeinvoice-pr -cv-compact_mono 0:5a136b6b9d8c -0.27 0.09 testharnessthatgatedeverytemplat -cv-compact_mono 0:d94eccbb1fbe -0.01 0.09 selectedprojects -cv-compact_mono 0:0059a3aac61e -0.56 0.09 graphcompose(java21,pdfbox,maven -cv-compact_mono 0:18b7f8c840e4 -0.53 0.09 dsl,slot-basedtemplates,snapshot -cv-compact_mono 0:d36f78e88fe0 -0.49 0.09 forhiringtoolsandbillingsystems. -cv-compact_mono 0:55e119878845 -0.48 0.09 templatestudio(kotlin,composedes -cv-compact_mono 0:c7b83853442b -0.45 0.09 proposal,andinvoiceoutputacross1 -cv-compact_mono 0:6b844249c695 -0.41 0.09 freezing. -cv-compact_mono 0:ab89138286bb -0.40 0.09 layoutlint(java21,javaparser,spo -cv-compact_mono 0:2c506ce69aa6 -0.37 0.09 nestedrows,untypedoffsets,implic -cv-compact_mono 0:6793d28e9783 -0.36 0.09 chromeforge(java,graphcompose,pa -cv-compact_mono 0:e3cfea265b3b -0.33 0.09 graphcompose:cinematiccovers,pul +cv-compact_mono 0:1900eab6c028 0.24 0.09 profile +cv-compact_mono 0:3828b9718a0d -0.35 0.09 platformengineerwith10+yearsbuil +cv-compact_mono 0:f6b5e93ccadd -0.34 0.09 engines,anddeveloper-facingtempl +cv-compact_mono 0:927ef106776a -0.33 0.09 semanticauthoringdsls,andturning +cv-compact_mono 0:330fcb75ed52 -0.32 0.09 librariesthatscale. +cv-compact_mono 0:53e5e7c5a884 0.31 0.09 experience +cv-compact_mono 0:c9efb118bfda -0.04 0.09 seniorplatformengineer,northwind +cv-compact_mono 0:64c4b52dceb1 -0.24 0.09 ledthereusabledocument-generatio +cv-compact_mono 0:1f193cd1d987 -0.22 0.09 productteams.reducedtemplatemain +cv-compact_mono 0:9ccc3e904e5a -0.20 0.09 favourofonecanonicalengine. +cv-compact_mono 0:e21e4e47835a 0.01 0.09 softwareengineer,brightleaflabs| +cv-compact_mono 0:0cdd48f05f9d -0.19 0.09 builtbackendservicesandproductio +cv-compact_mono 0:e48f1e2c853d -0.17 0.09 permonth.drovethemigrationfromit +cv-compact_mono 0:b78a9a72ca9a -0.15 0.09 andcuttingp99renderlatencyfrom1. +cv-compact_mono 0:9f5d87c00954 0.06 0.09 backendengineer,helixprintco|201 +cv-compact_mono 0:a485c37fe7ea -0.14 0.09 maintainedahigh-volumeinvoice-pr +cv-compact_mono 0:5a136b6b9d8c -0.12 0.09 testharnessthatgatedeverytemplat +cv-compact_mono 0:d94eccbb1fbe 0.49 0.09 selectedprojects +cv-compact_mono 0:0059a3aac61e -0.06 0.09 graphcompose(java21,pdfbox,maven +cv-compact_mono 0:18b7f8c840e4 -0.03 0.09 dsl,slot-basedtemplates,snapshot +cv-compact_mono 0:d36f78e88fe0 0.01 0.09 forhiringtoolsandbillingsystems. +cv-compact_mono 0:55e119878845 0.02 0.09 templatestudio(kotlin,composedes +cv-compact_mono 0:c7b83853442b 0.05 0.09 proposal,andinvoiceoutputacross1 +cv-compact_mono 0:6b844249c695 0.09 0.09 freezing. +cv-compact_mono 0:ab89138286bb 0.10 0.09 layoutlint(java21,javaparser,spo +cv-compact_mono 0:2c506ce69aa6 0.13 0.09 nestedrows,untypedoffsets,implic +cv-compact_mono 0:6793d28e9783 0.14 0.09 chromeforge(java,graphcompose,pa +cv-compact_mono 0:e3cfea265b3b 0.17 0.09 graphcompose:cinematiccovers,pul cv-editorial_blue 0:8f1010120ed6 0.45 0.12 jordanrivera cv-editorial_blue 0:2d58f0cadc2d 0.22 0.13 platformengineer cv-editorial_blue 0:1b28eb6a9a2e 0.14 0.13 +442055551000-london,uk @@ -449,56 +449,56 @@ cv-engineering_resume 0:89674e6f130e -0.20 0.34 +442055551000 cv-engineering_resume 0:e0f850305ded -0.19 0.25 jordan.rivera@example.com cv-engineering_resume 0:84308bea4540 -0.18 0.95 linkedin cv-engineering_resume 0:c0b0109d9439 -0.17 0.85 github -cv-engineering_resume 0:32c1cf49a2fe -0.50 0.10 skills -cv-engineering_resume 0:873a24d153c8 -0.44 0.10 languages:java21,kotlin,groovy,p -cv-engineering_resume 0:db84150190bb -0.63 0.10 document&print:pdfbox,apachepoi -cv-engineering_resume 0:69d03fef7130 -0.62 0.10 (docx/xlsx),itext,postscript,icc -cv-engineering_resume 0:d52fd337f016 -0.61 0.10 profiles -cv-engineering_resume 0:f93032b34754 -0.60 0.10 layoutengines:customdsldesign,se -cv-engineering_resume 0:2d6fa255ba3a -0.59 0.10 layouttrees,pagination,snapshott -cv-engineering_resume 0:f274537aaf2c -0.58 0.10 regression -cv-engineering_resume 0:45fcec9fa26d -0.57 0.10 build&infrastructure:maven,gradl -cv-engineering_resume 0:33ddf84f4bab -0.56 0.10 actions,jitpack,docker -cv-engineering_resume 0:af23376e2ec2 -0.55 0.10 testing:junit5,assertj,pdfbox-ba -cv-engineering_resume 0:a8c30cabf363 -0.54 0.10 diff,layout-graphsnapshots,mutat -cv-engineering_resume 0:7c093617a679 -0.53 0.10 (pitest) -cv-engineering_resume 0:11ca7190fe83 -0.52 0.10 distribution:mavencentral,sonaty -cv-engineering_resume 0:768ad260251b -0.51 0.10 gpgsigning,jitpack,semanticversi -cv-engineering_resume 0:d43c8bd5797a -0.50 0.10 discipline -cv-engineering_resume 0:68bf0109c6f8 -0.38 0.10 education -cv-engineering_resume 0:5f9c672fafaf -0.32 0.10 msccomputerscience/2019-2021 -cv-engineering_resume 0:141310eca6fb -0.31 0.10 bscsoftwareengineering/2015-2019 -cv-engineering_resume 0:608c03298f47 -0.30 0.10 oraclejavacertification/2023-202 -cv-engineering_resume 0:41ffd8b76afc -0.38 0.10 details -cv-engineering_resume 0:ecc25e73b19b -0.52 0.10 languages:english(fluent),german -cv-engineering_resume 0:ac7f0ee6a49e -0.51 0.10 (intermediate),spanish(basic) -cv-engineering_resume 0:970ca9d789c2 -0.50 0.10 workeligibility:eligibletoworkin -cv-engineering_resume 0:0735680e2596 -0.49 0.10 theeu -cv-engineering_resume 0:e8256e23459a -1.55 0.10 engineeringprofile -cv-engineering_resume 0:e9b75496bfb4 -1.65 0.10 platformengineerwith10+yearsbuil -cv-engineering_resume 0:866be9f7a132 -1.65 0.10 developer-facingtemplatesystems. -cv-engineering_resume 0:82c1650fbfe8 -1.65 0.10 dsls,andturningbrittleproduction -cv-engineering_resume 0:53e5e7c5a884 -1.55 0.10 experience -cv-engineering_resume 0:4977534824cc -1.46 0.10 seniorplatformengineer/2024-pres -cv-engineering_resume 0:f890faef907f -1.42 0.10 northwindsystems -cv-engineering_resume 0:0bf7eb0b1058 -1.66 0.10 ledthereusabledocument-generatio -cv-engineering_resume 0:d69cae607226 -1.64 0.10 teams.reducedtemplatemaintenance -cv-engineering_resume 0:bdea17333528 -1.62 0.10 engine. -cv-engineering_resume 0:7033b2988e4d -1.42 0.10 softwareengineer/2021-2024 -cv-engineering_resume 0:998c1a985022 -1.38 0.10 brightleaflabs -cv-engineering_resume 0:e77e909f6ff5 -1.62 0.10 builtbackendservicesandproductio -cv-engineering_resume 0:97c59b2fdb55 -1.60 0.10 drovethemigrationfromitexttoacus -cv-engineering_resume 0:2c2b19cf214d -1.58 0.10 latencyfrom1.4sto380ms. -cv-engineering_resume 0:8b5abdc8c0d7 -1.48 0.10 technicalevidence -cv-engineering_resume 0:e2fbf67cb588 -0.99 0.05 graphcompose(java21,pdfbox,maven -cv-engineering_resume 0:eb5950729749 -1.13 0.05 templates,snapshottesting.powers -cv-engineering_resume 0:81c8132f9792 -1.21 0.05 systems.(opensource) -cv-engineering_resume 0:643428f0ebf8 -1.02 0.05 templatestudio(kotlin,composedes -cv-engineering_resume 0:c259a0e7581e -1.31 0.05 invoiceoutputacross14designprese -cv-engineering_resume 0:c944ee08a5bf -1.12 0.05 layoutlint(java21,javaparser,spo -cv-engineering_resume 0:2d80d05697ad -1.41 0.05 untypedoffsets,implicitpagebreak -cv-engineering_resume 0:6793d28e9783 -1.22 0.05 chromeforge(java,graphcompose,pa -cv-engineering_resume 0:e3cfea265b3b -1.51 0.05 graphcompose:cinematiccovers,pul +cv-engineering_resume 0:32c1cf49a2fe -0.25 0.10 skills +cv-engineering_resume 0:873a24d153c8 -0.19 0.10 languages:java21,kotlin,groovy,p +cv-engineering_resume 0:db84150190bb -0.38 0.10 document&print:pdfbox,apachepoi +cv-engineering_resume 0:69d03fef7130 -0.37 0.10 (docx/xlsx),itext,postscript,icc +cv-engineering_resume 0:d52fd337f016 -0.36 0.10 profiles +cv-engineering_resume 0:f93032b34754 -0.35 0.10 layoutengines:customdsldesign,se +cv-engineering_resume 0:2d6fa255ba3a -0.34 0.10 layouttrees,pagination,snapshott +cv-engineering_resume 0:f274537aaf2c -0.33 0.10 regression +cv-engineering_resume 0:45fcec9fa26d -0.32 0.10 build&infrastructure:maven,gradl +cv-engineering_resume 0:33ddf84f4bab -0.31 0.10 actions,jitpack,docker +cv-engineering_resume 0:af23376e2ec2 -0.30 0.10 testing:junit5,assertj,pdfbox-ba +cv-engineering_resume 0:a8c30cabf363 -0.29 0.10 diff,layout-graphsnapshots,mutat +cv-engineering_resume 0:7c093617a679 -0.28 0.10 (pitest) +cv-engineering_resume 0:11ca7190fe83 -0.27 0.10 distribution:mavencentral,sonaty +cv-engineering_resume 0:768ad260251b -0.26 0.10 gpgsigning,jitpack,semanticversi +cv-engineering_resume 0:d43c8bd5797a -0.25 0.10 discipline +cv-engineering_resume 0:68bf0109c6f8 -0.13 0.10 education +cv-engineering_resume 0:5f9c672fafaf -0.07 0.10 msccomputerscience/2019-2021 +cv-engineering_resume 0:141310eca6fb -0.06 0.10 bscsoftwareengineering/2015-2019 +cv-engineering_resume 0:608c03298f47 -0.05 0.10 oraclejavacertification/2023-202 +cv-engineering_resume 0:41ffd8b76afc -0.13 0.10 details +cv-engineering_resume 0:ecc25e73b19b -0.27 0.10 languages:english(fluent),german +cv-engineering_resume 0:ac7f0ee6a49e -0.26 0.10 (intermediate),spanish(basic) +cv-engineering_resume 0:970ca9d789c2 -0.25 0.10 workeligibility:eligibletoworkin +cv-engineering_resume 0:0735680e2596 -0.24 0.10 theeu +cv-engineering_resume 0:e8256e23459a -0.30 0.10 engineeringprofile +cv-engineering_resume 0:e9b75496bfb4 -0.40 0.10 platformengineerwith10+yearsbuil +cv-engineering_resume 0:866be9f7a132 -0.40 0.10 developer-facingtemplatesystems. +cv-engineering_resume 0:82c1650fbfe8 -0.40 0.10 dsls,andturningbrittleproduction +cv-engineering_resume 0:53e5e7c5a884 -0.30 0.10 experience +cv-engineering_resume 0:4977534824cc -0.21 0.10 seniorplatformengineer/2024-pres +cv-engineering_resume 0:f890faef907f -0.17 0.10 northwindsystems +cv-engineering_resume 0:0bf7eb0b1058 -0.41 0.10 ledthereusabledocument-generatio +cv-engineering_resume 0:d69cae607226 -0.39 0.10 teams.reducedtemplatemaintenance +cv-engineering_resume 0:bdea17333528 -0.37 0.10 engine. +cv-engineering_resume 0:7033b2988e4d -0.17 0.10 softwareengineer/2021-2024 +cv-engineering_resume 0:998c1a985022 -0.13 0.10 brightleaflabs +cv-engineering_resume 0:e77e909f6ff5 -0.37 0.10 builtbackendservicesandproductio +cv-engineering_resume 0:97c59b2fdb55 -0.35 0.10 drovethemigrationfromitexttoacus +cv-engineering_resume 0:2c2b19cf214d -0.33 0.10 latencyfrom1.4sto380ms. +cv-engineering_resume 0:8b5abdc8c0d7 -0.23 0.10 technicalevidence +cv-engineering_resume 0:e2fbf67cb588 0.41 0.05 graphcompose(java21,pdfbox,maven +cv-engineering_resume 0:eb5950729749 0.27 0.05 templates,snapshottesting.powers +cv-engineering_resume 0:81c8132f9792 0.19 0.05 systems.(opensource) +cv-engineering_resume 0:643428f0ebf8 0.68 0.05 templatestudio(kotlin,composedes +cv-engineering_resume 0:c259a0e7581e 0.39 0.05 invoiceoutputacross14designprese +cv-engineering_resume 0:c944ee08a5bf 0.88 0.05 layoutlint(java21,javaparser,spo +cv-engineering_resume 0:2d80d05697ad 0.59 0.05 untypedoffsets,implicitpagebreak +cv-engineering_resume 0:6793d28e9783 1.08 0.05 chromeforge(java,graphcompose,pa +cv-engineering_resume 0:e3cfea265b3b 0.79 0.05 graphcompose:cinematiccovers,pul cv-executive 0:8f1010120ed6 -0.50 0.10 jordanrivera cv-executive 0:89ff05847e96 -0.28 0.10 london,uk|+442055551000 cv-executive 0:8817bf9310b6 -0.30 0.10 jordan.rivera@example.com|linked @@ -645,46 +645,46 @@ cv-midnight_navy 0:200b36afcfde -0.09 0.09 hubspotacademy cv-midnight_navy 0:1bea20e1df19 -0.11 0.09 2021 cv-minimal_underlined 0:8f1010120ed6 0.46 2.20 jordanrivera cv-minimal_underlined 0:8d7a2cca3060 0.18 0.22 +442055551000|jordan.rivera@exam -cv-minimal_underlined 0:b944906ed84c -0.11 0.10 professionalsummary -cv-minimal_underlined 0:80cc87fdc4c4 -0.72 0.10 platformengineerwith10+yearsbuil -cv-minimal_underlined 0:bddc0bd093ce -0.72 0.10 systems.specialisedinhigh-throug -cv-minimal_underlined 0:95a43d7b3df0 -0.71 0.10 snapshot-testedlibrariesthatscal -cv-minimal_underlined 0:5f94c50dc5bf -0.38 0.10 technicalskills -cv-minimal_underlined 0:eea537278f83 -0.70 0.10 •languages:java21,kotlin,groovy, -cv-minimal_underlined 0:9c2cd7231a53 -0.69 0.10 •document&print:pdfbox,apachepoi -cv-minimal_underlined 0:7bf8639ec5d3 -0.69 0.10 •layoutengines:customdsldesign,s -cv-minimal_underlined 0:8e66776d28d7 -0.68 0.10 •build&infrastructure:maven,grad -cv-minimal_underlined 0:1ed4fc7d7768 -0.68 0.10 •testing:junit5,assertj,pdfbox-b -cv-minimal_underlined 0:26671c309eb9 -0.67 0.10 •distribution:mavencentral,sonat -cv-minimal_underlined 0:68bf0109c6f8 -0.64 0.10 education -cv-minimal_underlined 0:0ad1957d6bab -0.93 0.10 msccomputerscience -cv-minimal_underlined 0:3fa772117260 -0.97 -0.76 2019-2021 -cv-minimal_underlined 0:47ce0218bbea -0.94 0.10 universityofmanchester -cv-minimal_underlined 0:2ffe115b06e5 -0.93 0.10 distinction.thesis:composablelay -cv-minimal_underlined 0:b6749d0b616b -0.90 0.10 bscsoftwareengineering -cv-minimal_underlined 0:30f9262640a0 -0.93 -0.76 2015-2019 -cv-minimal_underlined 0:89ad9656f393 -0.91 0.10 imperialcollegelondon -cv-minimal_underlined 0:baa173b4a82e -0.89 0.10 first-classhonours.specialisatio -cv-minimal_underlined 0:6d3d5673c39f -0.86 0.10 oraclejavacertification -cv-minimal_underlined 0:d40b22f00acb -0.90 -0.76 2023-2024 -cv-minimal_underlined 0:2669e1f6d55c -0.87 0.10 professionaltrack -cv-minimal_underlined 0:3857373829c1 -0.86 0.10 java17platformdeep-dive:records, -cv-minimal_underlined 0:2577c0f557b2 -0.83 0.10 projects -cv-minimal_underlined 0:b2b029995203 -1.14 0.10 •graphcompose(java21,pdfbox,mave -cv-minimal_underlined 0:67593a76ef70 -1.44 0.11 declarativejavapdflayoutengine.s -cv-minimal_underlined 0:b9292cbd1454 -1.43 0.11 pipelinesforhiringtoolsandbillin -cv-minimal_underlined 0:1b50bb81df5a -1.13 0.10 •templatestudio(kotlin,composede -cv-minimal_underlined 0:7127a108c33c -1.42 0.11 internaltoolforevaluatingcv,prop -cv-minimal_underlined 0:6b844249c695 -1.42 0.11 freezing. -cv-minimal_underlined 0:25cdca2beb8b -1.11 0.10 •layoutlint(java21,javaparser,sp -cv-minimal_underlined 0:7488006d7864 -1.41 0.11 staticanalyserthatflagsfragileau -cv-minimal_underlined 0:c4d0c415b4f8 -1.40 0.11 production. -cv-minimal_underlined 0:fb1927f88597 -1.10 0.10 •chromeforge(java,graphcompose,p -cv-minimal_underlined 0:e7e62230eb1f -1.09 0.11 editorial-magazinedocumenttoolki -cv-minimal_underlined 0:c2f296ef30a3 -1.06 0.10 professionalexperience -cv-minimal_underlined 0:a76f47480818 -1.35 0.10 seniorplatformengineer -cv-minimal_underlined 0:060300b18051 -1.39 0.01 2024-present -cv-minimal_underlined 0:f890faef907f -1.36 0.10 northwindsystems +cv-minimal_underlined 0:b944906ed84c 0.24 0.10 professionalsummary +cv-minimal_underlined 0:80cc87fdc4c4 -0.02 0.10 platformengineerwith10+yearsbuil +cv-minimal_underlined 0:bddc0bd093ce -0.02 0.10 systems.specialisedinhigh-throug +cv-minimal_underlined 0:95a43d7b3df0 -0.01 0.10 snapshot-testedlibrariesthatscal +cv-minimal_underlined 0:5f94c50dc5bf 0.32 0.10 technicalskills +cv-minimal_underlined 0:eea537278f83 0.35 0.10 •languages:java21,kotlin,groovy, +cv-minimal_underlined 0:9c2cd7231a53 0.36 0.10 •document&print:pdfbox,apachepoi +cv-minimal_underlined 0:7bf8639ec5d3 0.36 0.10 •layoutengines:customdsldesign,s +cv-minimal_underlined 0:8e66776d28d7 0.37 0.10 •build&infrastructure:maven,grad +cv-minimal_underlined 0:1ed4fc7d7768 0.37 0.10 •testing:junit5,assertj,pdfbox-b +cv-minimal_underlined 0:26671c309eb9 0.38 0.10 •distribution:mavencentral,sonat +cv-minimal_underlined 0:68bf0109c6f8 0.41 0.10 education +cv-minimal_underlined 0:0ad1957d6bab 0.47 0.10 msccomputerscience +cv-minimal_underlined 0:3fa772117260 0.43 -0.76 2019-2021 +cv-minimal_underlined 0:47ce0218bbea 0.46 0.10 universityofmanchester +cv-minimal_underlined 0:2ffe115b06e5 0.47 0.10 distinction.thesis:composablelay +cv-minimal_underlined 0:b6749d0b616b 0.50 0.10 bscsoftwareengineering +cv-minimal_underlined 0:30f9262640a0 0.47 -0.76 2015-2019 +cv-minimal_underlined 0:89ad9656f393 0.49 0.10 imperialcollegelondon +cv-minimal_underlined 0:baa173b4a82e 0.51 0.10 first-classhonours.specialisatio +cv-minimal_underlined 0:6d3d5673c39f 0.54 0.10 oraclejavacertification +cv-minimal_underlined 0:d40b22f00acb 0.50 -0.76 2023-2024 +cv-minimal_underlined 0:2669e1f6d55c 0.53 0.10 professionaltrack +cv-minimal_underlined 0:3857373829c1 0.54 0.10 java17platformdeep-dive:records, +cv-minimal_underlined 0:2577c0f557b2 0.57 0.10 projects +cv-minimal_underlined 0:b2b029995203 0.61 0.10 •graphcompose(java21,pdfbox,mave +cv-minimal_underlined 0:67593a76ef70 0.31 0.11 declarativejavapdflayoutengine.s +cv-minimal_underlined 0:b9292cbd1454 0.32 0.11 pipelinesforhiringtoolsandbillin +cv-minimal_underlined 0:1b50bb81df5a 0.62 0.10 •templatestudio(kotlin,composede +cv-minimal_underlined 0:7127a108c33c 0.33 0.11 internaltoolforevaluatingcv,prop +cv-minimal_underlined 0:6b844249c695 0.33 0.11 freezing. +cv-minimal_underlined 0:25cdca2beb8b 0.64 0.10 •layoutlint(java21,javaparser,sp +cv-minimal_underlined 0:7488006d7864 0.34 0.11 staticanalyserthatflagsfragileau +cv-minimal_underlined 0:c4d0c415b4f8 0.35 0.11 production. +cv-minimal_underlined 0:fb1927f88597 0.65 0.10 •chromeforge(java,graphcompose,p +cv-minimal_underlined 0:e7e62230eb1f 0.66 0.11 editorial-magazinedocumenttoolki +cv-minimal_underlined 0:c2f296ef30a3 0.69 0.10 professionalexperience +cv-minimal_underlined 0:a76f47480818 0.75 0.10 seniorplatformengineer +cv-minimal_underlined 0:060300b18051 0.71 0.01 2024-present +cv-minimal_underlined 0:f890faef907f 0.74 0.10 northwindsystems cv-minimal_underlined 1:49faf14f1f56 -0.13 0.10 ledthereusabledocument-generatio cv-minimal_underlined 1:6bd3f168e89e -0.13 0.10 maintenancetimeby70%byretiringpe cv-minimal_underlined 1:daf65306b3b6 0.20 0.10 softwareengineer @@ -698,10 +698,10 @@ cv-minimal_underlined 1:ef148f221e31 0.23 0.10 helixprintco cv-minimal_underlined 1:9d31a6bfbc69 -0.05 0.10 maintainedahigh-volumeinvoice-pr cv-minimal_underlined 1:03af8a628309 -0.05 0.10 change. cv-minimal_underlined 1:676dfdd56ad2 0.28 0.10 additionalinformation -cv-minimal_underlined 1:f20997652453 -0.03 0.10 languages:english(fluent),german -cv-minimal_underlined 1:ec9d3622395e -0.03 0.10 workeligibility:eligibletoworkin -cv-minimal_underlined 1:dd20ae01c3cf -0.02 0.10 opensource:maintainerofgraphcomp -cv-minimal_underlined 1:33c35e9d236d -0.02 0.10 speaking:jvmsummit2024,devoxxuk2 +cv-minimal_underlined 1:f20997652453 0.32 0.10 languages:english(fluent),german +cv-minimal_underlined 1:ec9d3622395e 0.32 0.10 workeligibility:eligibletoworkin +cv-minimal_underlined 1:dd20ae01c3cf 0.33 0.10 opensource:maintainerofgraphcomp +cv-minimal_underlined 1:33c35e9d236d 0.33 0.10 speaking:jvmsummit2024,devoxxuk2 cv-mint_editorial 0:8f1010120ed6 -1.30 2.33 jordanrivera cv-mint_editorial 0:2d58f0cadc2d -0.27 0.12 platformengineer cv-mint_editorial 0:093e7d5fdbaa -0.71 0.10 contact @@ -764,57 +764,57 @@ cv-mint_editorial 1:1081945512b1 0.39 0.07 authoredthecompliancetestharness cv-modern_professional 0:8f1010120ed6 0.00 0.21 jordanrivera cv-modern_professional 0:89ff05847e96 0.14 0.26 london,uk|+442055551000 cv-modern_professional 0:8817bf9310b6 0.11 0.30 jordan.rivera@example.com|linked -cv-modern_professional 0:b944906ed84c 0.01 0.10 professionalsummary -cv-modern_professional 0:6fbdc8b79878 -0.42 0.10 platformengineerwith10+yearsbuil -cv-modern_professional 0:5f94c50dc5bf 0.01 0.10 technicalskills -cv-modern_professional 0:eea537278f83 -0.12 0.10 •languages:java21,kotlin,groovy, -cv-modern_professional 0:9c2cd7231a53 -0.12 0.10 •document&print:pdfbox,apachepoi -cv-modern_professional 0:7bf8639ec5d3 -0.12 0.10 •layoutengines:customdsldesign,s -cv-modern_professional 0:8e66776d28d7 -0.12 0.10 •build&infrastructure:maven,grad -cv-modern_professional 0:1ed4fc7d7768 -0.12 0.10 •testing:junit5,assertj,pdfbox-b -cv-modern_professional 0:26671c309eb9 -0.12 0.10 •distribution:mavencentral,sonat -cv-modern_professional 0:68bf0109c6f8 0.02 0.10 education -cv-modern_professional 0:0ad1957d6bab -0.12 0.10 msccomputerscience -cv-modern_professional 0:3fa772117260 -0.11 0.18 2019-2021 -cv-modern_professional 0:3fa772117260#1 -0.10 0.18 2019-2021 -cv-modern_professional 0:47ce0218bbea -0.17 0.10 universityofmanchester -cv-modern_professional 0:2ffe115b06e5 -0.11 0.10 distinction.thesis:composablelay -cv-modern_professional 0:b6749d0b616b -0.12 0.10 bscsoftwareengineering -cv-modern_professional 0:30f9262640a0 -0.11 0.18 2015-2019 -cv-modern_professional 0:89ad9656f393 -0.17 0.10 imperialcollegelondon -cv-modern_professional 0:baa173b4a82e -0.11 0.10 first-classhonours.specialisatio -cv-modern_professional 0:6d3d5673c39f -0.12 0.10 oraclejavacertification -cv-modern_professional 0:d40b22f00acb -0.11 0.18 2023-2024 -cv-modern_professional 0:2669e1f6d55c -0.17 0.10 professionaltrack -cv-modern_professional 0:3857373829c1 -0.11 0.10 java17platformdeep-dive:records, -cv-modern_professional 0:2577c0f557b2 0.02 0.10 projects -cv-modern_professional 0:b2b029995203 -0.11 0.10 •graphcompose(java21,pdfbox,mave -cv-modern_professional 0:dd39d2ff3520 -0.41 0.10 declarativejavapdflayoutengine.s -cv-modern_professional 0:9ecaa6df6d41 -0.41 0.10 invoice/proposalpipelinesforhiri -cv-modern_professional 0:1b50bb81df5a -0.11 0.10 •templatestudio(kotlin,composede -cv-modern_professional 0:18eec9e76e2d -0.41 0.10 internaltoolforevaluatingcv,prop -cv-modern_professional 0:6bc2807453c6 -0.41 0.10 baselinefreezing. -cv-modern_professional 0:25cdca2beb8b -0.11 0.10 •layoutlint(java21,javaparser,sp -cv-modern_professional 0:cc2850ddd8ba -0.41 0.10 staticanalyserthatflagsfragileau -cv-modern_professional 0:7b985a1d2b08 -0.41 0.10 shiptoproduction. -cv-modern_professional 0:fb1927f88597 -0.11 0.10 •chromeforge(java,graphcompose,p -cv-modern_professional 0:cda7db6c6ea6 -0.41 0.10 editorial-magazinedocumenttoolki -cv-modern_professional 0:fe63fe18585a -0.41 0.10 callouts. -cv-modern_professional 0:c2f296ef30a3 0.03 0.10 professionalexperience -cv-modern_professional 0:a76f47480818 -0.11 0.10 seniorplatformengineer -cv-modern_professional 0:060300b18051 -0.10 0.20 2024-present -cv-modern_professional 0:f890faef907f -0.16 0.10 northwindsystems -cv-modern_professional 0:a6525dacbac7 -0.40 0.10 ledthereusabledocument-generatio -cv-modern_professional 0:15e3905f4890 -0.40 0.10 reducedtemplatemaintenancetimeby -cv-modern_professional 0:daf65306b3b6 -0.11 0.10 softwareengineer -cv-modern_professional 0:e7cc1822c6dc -0.10 0.18 2021-2024 -cv-modern_professional 0:998c1a985022 -0.16 0.10 brightleaflabs -cv-modern_professional 0:e86691b0219f -0.40 0.10 builtbackendservicesandproductio -cv-modern_professional 0:4ec57434564a -0.40 0.10 migrationfromitexttoacustomlayou -cv-modern_professional 0:41bb54fbae8d -0.11 0.10 backendengineer -cv-modern_professional 0:ef148f221e31 -0.16 0.10 helixprintco -cv-modern_professional 0:a32c7f2401d9 -0.40 0.10 maintainedahigh-volumeinvoice-pr -cv-modern_professional 0:7068c1d7034b -0.40 0.10 everytemplatechange. +cv-modern_professional 0:b944906ed84c 0.41 0.10 professionalsummary +cv-modern_professional 0:6fbdc8b79878 -0.02 0.10 platformengineerwith10+yearsbuil +cv-modern_professional 0:5f94c50dc5bf 0.41 0.10 technicalskills +cv-modern_professional 0:eea537278f83 0.28 0.10 •languages:java21,kotlin,groovy, +cv-modern_professional 0:9c2cd7231a53 0.28 0.10 •document&print:pdfbox,apachepoi +cv-modern_professional 0:7bf8639ec5d3 0.28 0.10 •layoutengines:customdsldesign,s +cv-modern_professional 0:8e66776d28d7 0.28 0.10 •build&infrastructure:maven,grad +cv-modern_professional 0:1ed4fc7d7768 0.28 0.10 •testing:junit5,assertj,pdfbox-b +cv-modern_professional 0:26671c309eb9 0.28 0.10 •distribution:mavencentral,sonat +cv-modern_professional 0:68bf0109c6f8 0.42 0.10 education +cv-modern_professional 0:0ad1957d6bab 0.28 0.10 msccomputerscience +cv-modern_professional 0:3fa772117260 0.29 0.18 2019-2021 +cv-modern_professional 0:3fa772117260#1 0.30 0.18 2019-2021 +cv-modern_professional 0:47ce0218bbea 0.23 0.10 universityofmanchester +cv-modern_professional 0:2ffe115b06e5 0.29 0.10 distinction.thesis:composablelay +cv-modern_professional 0:b6749d0b616b 0.28 0.10 bscsoftwareengineering +cv-modern_professional 0:30f9262640a0 0.29 0.18 2015-2019 +cv-modern_professional 0:89ad9656f393 0.23 0.10 imperialcollegelondon +cv-modern_professional 0:baa173b4a82e 0.29 0.10 first-classhonours.specialisatio +cv-modern_professional 0:6d3d5673c39f 0.28 0.10 oraclejavacertification +cv-modern_professional 0:d40b22f00acb 0.29 0.18 2023-2024 +cv-modern_professional 0:2669e1f6d55c 0.23 0.10 professionaltrack +cv-modern_professional 0:3857373829c1 0.29 0.10 java17platformdeep-dive:records, +cv-modern_professional 0:2577c0f557b2 0.42 0.10 projects +cv-modern_professional 0:b2b029995203 0.29 0.10 •graphcompose(java21,pdfbox,mave +cv-modern_professional 0:dd39d2ff3520 -0.01 0.10 declarativejavapdflayoutengine.s +cv-modern_professional 0:9ecaa6df6d41 -0.01 0.10 invoice/proposalpipelinesforhiri +cv-modern_professional 0:1b50bb81df5a 0.29 0.10 •templatestudio(kotlin,composede +cv-modern_professional 0:18eec9e76e2d -0.01 0.10 internaltoolforevaluatingcv,prop +cv-modern_professional 0:6bc2807453c6 -0.01 0.10 baselinefreezing. +cv-modern_professional 0:25cdca2beb8b 0.29 0.10 •layoutlint(java21,javaparser,sp +cv-modern_professional 0:cc2850ddd8ba -0.01 0.10 staticanalyserthatflagsfragileau +cv-modern_professional 0:7b985a1d2b08 -0.01 0.10 shiptoproduction. +cv-modern_professional 0:fb1927f88597 0.29 0.10 •chromeforge(java,graphcompose,p +cv-modern_professional 0:cda7db6c6ea6 -0.01 0.10 editorial-magazinedocumenttoolki +cv-modern_professional 0:fe63fe18585a -0.01 0.10 callouts. +cv-modern_professional 0:c2f296ef30a3 0.43 0.10 professionalexperience +cv-modern_professional 0:a76f47480818 0.29 0.10 seniorplatformengineer +cv-modern_professional 0:060300b18051 0.30 0.20 2024-present +cv-modern_professional 0:f890faef907f 0.24 0.10 northwindsystems +cv-modern_professional 0:a6525dacbac7 0.00 0.10 ledthereusabledocument-generatio +cv-modern_professional 0:15e3905f4890 0.00 0.10 reducedtemplatemaintenancetimeby +cv-modern_professional 0:daf65306b3b6 0.29 0.10 softwareengineer +cv-modern_professional 0:e7cc1822c6dc 0.30 0.18 2021-2024 +cv-modern_professional 0:998c1a985022 0.24 0.10 brightleaflabs +cv-modern_professional 0:e86691b0219f 0.00 0.10 builtbackendservicesandproductio +cv-modern_professional 0:4ec57434564a 0.00 0.10 migrationfromitexttoacustomlayou +cv-modern_professional 0:41bb54fbae8d 0.29 0.10 backendengineer +cv-modern_professional 0:ef148f221e31 0.24 0.10 helixprintco +cv-modern_professional 0:a32c7f2401d9 0.00 0.10 maintainedahigh-volumeinvoice-pr +cv-modern_professional 0:7068c1d7034b 0.00 0.10 everytemplatechange. cv-modern_professional 1:676dfdd56ad2 0.36 0.10 additionalinformation cv-modern_professional 1:f20997652453 0.23 0.10 languages:english(fluent),german cv-modern_professional 1:ec9d3622395e 0.23 0.10 workeligibility:eligibletoworkin @@ -951,32 +951,32 @@ cv-nordic_clean 0:c0b0109d9439 -0.12 -0.11 github cv-nordic_clean 0:1900eab6c028 -0.25 0.10 profile cv-nordic_clean 0:8d6758a29c08 -0.42 0.10 platformengineerwith10+yearsbuil cv-nordic_clean 0:f0d993eb5f9d -0.44 0.10 high-throughputpdfrendering,sema -cv-nordic_clean 0:32c1cf49a2fe -0.06 0.10 skills -cv-nordic_clean 0:873a24d153c8 0.06 0.10 languages:java21,kotlin,groovy,p -cv-nordic_clean 0:db84150190bb -0.12 0.10 document&print:pdfbox,apachepoi -cv-nordic_clean 0:1d1d129512e6 -0.10 0.10 (docx/xlsx),itext,postscript,icc -cv-nordic_clean 0:7985eee03934 -0.08 0.10 fontmetrics -cv-nordic_clean 0:a1cec3782701 -0.06 0.10 layoutengines:customdsldesign,se -cv-nordic_clean 0:3a3b8c3bddd0 -0.04 0.10 trees,pagination,snapshottesting -cv-nordic_clean 0:b7d8ca9428a4 -0.02 0.10 build&infrastructure:maven,gradl -cv-nordic_clean 0:656a2a3e57e0 0.00 0.10 jitpack,docker,jmhbenchmarking -cv-nordic_clean 0:b8b1a42a45e1 0.02 0.10 testing:junit5,assertj,pdfbox-ba -cv-nordic_clean 0:2ec2836b6df6 0.04 0.10 layout-graphsnapshots,mutationte -cv-nordic_clean 0:74b69eb8de4b 0.06 0.10 distribution:mavencentral,sonaty -cv-nordic_clean 0:43ad67a4e3f5 0.08 0.10 signing,jitpack,semanticversioni -cv-nordic_clean 0:68bf0109c6f8 0.16 0.10 education -cv-nordic_clean 0:904a600c3869 0.08 0.10 msccomputerscience/universityofm -cv-nordic_clean 0:3fa772117260 0.27 0.10 2019-2021 -cv-nordic_clean 0:78a380e4d1f0 0.30 0.10 bscsoftwareengineering/imperialc -cv-nordic_clean 0:30f9262640a0 0.49 0.10 2015-2019 -cv-nordic_clean 0:7b476727faf3 0.80 0.10 additional -cv-nordic_clean 0:3b0f5db9217f 0.67 0.10 languages:english(fluent),german -cv-nordic_clean 0:d8a971cea795 0.65 0.10 spanish(basic) -cv-nordic_clean 0:ec9d3622395e 0.88 0.10 workeligibility:eligibletoworkin -cv-nordic_clean 0:d05b8b335e96 0.61 0.10 opensource:maintainerofgraphcomp -cv-nordic_clean 0:2f3b4176123d 0.59 0.10 contributortopdfboxissuetriage. -cv-nordic_clean 0:b6b5a250cb72 0.57 0.10 speaking:jvmsummit2024,devoxxuk2 -cv-nordic_clean 0:7ead14c50085 0.55 0.10 ondeclarativedocumentlayout. +cv-nordic_clean 0:32c1cf49a2fe -0.26 0.10 skills +cv-nordic_clean 0:873a24d153c8 -0.14 0.10 languages:java21,kotlin,groovy,p +cv-nordic_clean 0:db84150190bb -0.32 0.10 document&print:pdfbox,apachepoi +cv-nordic_clean 0:1d1d129512e6 -0.30 0.10 (docx/xlsx),itext,postscript,icc +cv-nordic_clean 0:7985eee03934 -0.28 0.10 fontmetrics +cv-nordic_clean 0:a1cec3782701 -0.26 0.10 layoutengines:customdsldesign,se +cv-nordic_clean 0:3a3b8c3bddd0 -0.24 0.10 trees,pagination,snapshottesting +cv-nordic_clean 0:b7d8ca9428a4 -0.22 0.10 build&infrastructure:maven,gradl +cv-nordic_clean 0:656a2a3e57e0 -0.20 0.10 jitpack,docker,jmhbenchmarking +cv-nordic_clean 0:b8b1a42a45e1 -0.18 0.10 testing:junit5,assertj,pdfbox-ba +cv-nordic_clean 0:2ec2836b6df6 -0.16 0.10 layout-graphsnapshots,mutationte +cv-nordic_clean 0:74b69eb8de4b -0.14 0.10 distribution:mavencentral,sonaty +cv-nordic_clean 0:43ad67a4e3f5 -0.12 0.10 signing,jitpack,semanticversioni +cv-nordic_clean 0:68bf0109c6f8 -0.04 0.10 education +cv-nordic_clean 0:904a600c3869 -0.12 0.10 msccomputerscience/universityofm +cv-nordic_clean 0:3fa772117260 0.07 0.10 2019-2021 +cv-nordic_clean 0:78a380e4d1f0 0.10 0.10 bscsoftwareengineering/imperialc +cv-nordic_clean 0:30f9262640a0 0.29 0.10 2015-2019 +cv-nordic_clean 0:7b476727faf3 0.60 0.10 additional +cv-nordic_clean 0:3b0f5db9217f 0.47 0.10 languages:english(fluent),german +cv-nordic_clean 0:d8a971cea795 0.45 0.10 spanish(basic) +cv-nordic_clean 0:ec9d3622395e 0.68 0.10 workeligibility:eligibletoworkin +cv-nordic_clean 0:d05b8b335e96 0.41 0.10 opensource:maintainerofgraphcomp +cv-nordic_clean 0:2f3b4176123d 0.39 0.10 contributortopdfboxissuetriage. +cv-nordic_clean 0:b6b5a250cb72 0.37 0.10 speaking:jvmsummit2024,devoxxuk2 +cv-nordic_clean 0:7ead14c50085 0.35 0.10 ondeclarativedocumentlayout. cv-nordic_clean 0:53e5e7c5a884 -0.26 0.11 experience cv-nordic_clean 0:4977534824cc -0.18 0.11 seniorplatformengineer/2024-pres cv-nordic_clean 0:f890faef907f -0.14 0.11 northwindsystems @@ -1004,80 +1004,80 @@ cv-orange_ops 0:a8acc3a90a7b 77.92 -0.03 +447700900123 cv-orange_ops 0:e6da1125d5d5 77.92 -0.42 marcus.bennett@email.com cv-orange_ops 0:6a3bd39f358d 77.92 -0.78 birmingham,westmidlands,uk cv-orange_ops 0:84308bea4540 77.92 -1.07 linkedin -cv-panel 0:8f1010120ed6 -0.40 0.32 jordanrivera -cv-panel 0:2d58f0cadc2d 0.12 0.07 platformengineer -cv-panel 0:89ff05847e96 0.19 0.29 london,uk|+442055551000 -cv-panel 0:8817bf9310b6 0.21 0.35 jordan.rivera@example.com|linked -cv-panel 0:1900eab6c028 0.19 0.10 profile -cv-panel 0:80cc87fdc4c4 -0.23 0.10 platformengineerwith10+yearsbuil -cv-panel 0:c323ef4c385f -0.21 0.10 systems.specialisedinhigh-throug -cv-panel 0:3ff1933dba9a -0.19 0.10 typed,snapshot-testedlibrariesth -cv-panel 0:32c1cf49a2fe 0.49 0.15 skills -cv-panel 0:eea537278f83 0.27 0.15 •languages:java21,kotlin,groovy, -cv-panel 0:7e941e729572 0.09 0.15 •document&print:pdfbox,apachepoi -cv-panel 0:9e3166ce2413 0.11 0.15 itext,postscript,icccolourprofil -cv-panel 0:ebc70ed9b71b 0.13 0.15 •layoutengines:customdsldesign,s -cv-panel 0:dd4f24d85605 0.15 0.15 pagination,snapshottesting,visua -cv-panel 0:f5f76d479ec8 0.17 0.15 •build&infrastructure:maven,grad -cv-panel 0:656a2a3e57e0 0.19 0.15 jitpack,docker,jmhbenchmarking -cv-panel 0:9a6921f79b7d 0.25 0.15 •distribution:mavencentral,sonat -cv-panel 0:77a74982066f 0.27 0.15 jitpack,semanticversioningdiscip -cv-panel 0:68bf0109c6f8 0.50 0.15 education -cv-panel 0:871923f4f0f2 0.28 0.15 msccomputerscience-2019-2021 -cv-panel 0:47ce0218bbea 0.30 0.15 universityofmanchester -cv-panel 0:51e1ec7daa5a 0.10 0.15 distinction.thesis:composablelay -cv-panel 0:d10553cd7368 0.12 0.15 deterministicdocumentrendering. -cv-panel 0:ba6d361079f4 0.34 0.15 bscsoftwareengineering-2015-2019 -cv-panel 0:89ad9656f393 0.36 0.15 imperialcollegelondon -cv-panel 0:4c58bcad7242 0.16 0.15 first-classhonours.specialisatio -cv-panel 0:2189b9b3b549 0.18 0.15 analysis. -cv-panel 0:8971b01c36bb 0.40 0.15 oraclejavacertification-2023-202 -cv-panel 0:2669e1f6d55c 0.42 0.15 professionaltrack -cv-panel 0:4f17e3d7d6f4 0.22 0.15 java17platformdeep-dive:records, -cv-panel 0:9e6154a3b625 0.24 0.15 matching,virtualthreads. -cv-panel 0:7b476727faf3 0.47 0.15 additional -cv-panel 0:3f88eb4c530c 0.05 0.15 languages:english(fluent),german -cv-panel 0:5d276fee8c17 0.07 0.15 (basic) -cv-panel 0:ec9d3622395e 0.29 0.15 workeligibility:eligibletoworkin -cv-panel 0:d05b8b335e96 0.11 0.15 opensource:maintainerofgraphcomp -cv-panel 0:2f3b4176123d 0.13 0.15 contributortopdfboxissuetriage. -cv-panel 0:1ae173b42166 0.15 0.15 speaking:jvmsummit2024,devoxxuk2 -cv-panel 0:309255ca6a36 0.17 0.15 declarativedocumentlayout. -cv-panel 0:53e5e7c5a884 0.49 0.16 experience -cv-panel 0:99b44abc1b3e 0.27 0.16 seniorplatformengineer-2024-pres -cv-panel 0:f890faef907f 0.29 0.16 northwindsystems -cv-panel 0:e32ca827bfd5 0.09 0.16 ledthereusabledocument-generatio -cv-panel 0:675f8862fdda 0.11 0.16 hiring,andreportingflowsacross8p -cv-panel 0:93d48fc85054 0.13 0.16 templatemaintenancetimeby70%byre -cv-panel 0:e7f09e2ba7d2 0.15 0.16 scriptsinfavourofonecanonicaleng -cv-panel 0:ded138c59d03 0.37 0.16 softwareengineer-2021-2024 -cv-panel 0:998c1a985022 0.39 0.16 brightleaflabs -cv-panel 0:0ed66ac9265d 0.19 0.16 builtbackendservicesandproductio -cv-panel 0:17c4ef49d4e6 0.21 0.16 pipelinesprocessing2m+documentsp -cv-panel 0:a7dd3c5be76b 0.23 0.16 migrationfromitexttoacustomlayou -cv-panel 0:a35401d8bcad 0.25 0.16 licensingriskandcuttingp99render -cv-panel 0:649d2d9d10d0 0.27 0.16 380ms. -cv-panel 0:019bbdc8d0bb 0.49 0.16 backendengineer-2019-2021 -cv-panel 0:ef148f221e31 0.51 0.16 helixprintco -cv-panel 0:09cc06a649eb 0.31 0.16 maintainedahigh-volumeinvoice-pr -cv-panel 0:090e2184c17b 0.33 0.16 pdfs/year)andauthoredthecomplian -cv-panel 0:6f071fdf7529 0.35 0.16 gatedeverytemplatechange. -cv-panel 0:2577c0f557b2 0.58 0.16 projects -cv-panel 0:b2b029995203 0.36 0.16 •graphcompose(java21,pdfbox,mave -cv-panel 0:81c8132f9792 0.24 0.16 systems.(opensource) -cv-panel 0:753f46e4e01b 0.26 0.16 •templatestudio(kotlin,composede -cv-panel 0:6eb35b5b9a91 0.28 0.16 diff) -cv-panel 0:d919bd2d50b6 0.30 0.16 internaltoolforevaluatingcv,prop -cv-panel 0:245b9e56b9de 0.32 0.16 across14designpresets.pngdiffing -cv-panel 0:6bc2807453c6 0.34 0.16 baselinefreezing. -cv-panel 0:25cdca2beb8b 0.56 0.16 •layoutlint(java21,javaparser,sp -cv-panel 0:30e034b9c7b2 0.38 0.16 staticanalyserthatflagsfragileau -cv-panel 0:e7ad19d64668 0.40 0.16 nestedrows,untypedoffsets,implic -cv-panel 0:95ac1a62c76f 0.42 0.16 theyshiptoproduction. -cv-panel 0:fb1927f88597 0.64 0.16 •chromeforge(java,graphcompose,p -cv-panel 0:bb865a4ccac1 0.46 0.16 editorial-magazinedocumenttoolki -cv-panel 0:8a31ccd889ee 0.48 0.16 cinematiccovers,pullquotes,multi -cv-panel 0:fe63fe18585a 0.50 0.16 callouts. +cv-panel 0:8f1010120ed6 -0.65 0.32 jordanrivera +cv-panel 0:2d58f0cadc2d -0.13 0.07 platformengineer +cv-panel 0:89ff05847e96 -0.06 0.29 london,uk|+442055551000 +cv-panel 0:8817bf9310b6 -0.04 0.35 jordan.rivera@example.com|linked +cv-panel 0:1900eab6c028 0.39 0.10 profile +cv-panel 0:80cc87fdc4c4 -0.03 0.10 platformengineerwith10+yearsbuil +cv-panel 0:c323ef4c385f -0.01 0.10 systems.specialisedinhigh-throug +cv-panel 0:3ff1933dba9a 0.01 0.10 typed,snapshot-testedlibrariesth +cv-panel 0:32c1cf49a2fe 0.69 0.15 skills +cv-panel 0:eea537278f83 0.47 0.15 •languages:java21,kotlin,groovy, +cv-panel 0:7e941e729572 0.29 0.15 •document&print:pdfbox,apachepoi +cv-panel 0:9e3166ce2413 0.31 0.15 itext,postscript,icccolourprofil +cv-panel 0:ebc70ed9b71b 0.33 0.15 •layoutengines:customdsldesign,s +cv-panel 0:dd4f24d85605 0.35 0.15 pagination,snapshottesting,visua +cv-panel 0:f5f76d479ec8 0.37 0.15 •build&infrastructure:maven,grad +cv-panel 0:656a2a3e57e0 0.39 0.15 jitpack,docker,jmhbenchmarking +cv-panel 0:9a6921f79b7d 0.45 0.15 •distribution:mavencentral,sonat +cv-panel 0:77a74982066f 0.47 0.15 jitpack,semanticversioningdiscip +cv-panel 0:68bf0109c6f8 1.15 0.15 education +cv-panel 0:871923f4f0f2 0.93 0.15 msccomputerscience-2019-2021 +cv-panel 0:47ce0218bbea 0.95 0.15 universityofmanchester +cv-panel 0:51e1ec7daa5a 0.75 0.15 distinction.thesis:composablelay +cv-panel 0:d10553cd7368 0.77 0.15 deterministicdocumentrendering. +cv-panel 0:ba6d361079f4 0.99 0.15 bscsoftwareengineering-2015-2019 +cv-panel 0:89ad9656f393 1.01 0.15 imperialcollegelondon +cv-panel 0:4c58bcad7242 0.81 0.15 first-classhonours.specialisatio +cv-panel 0:2189b9b3b549 0.83 0.15 analysis. +cv-panel 0:8971b01c36bb 1.05 0.15 oraclejavacertification-2023-202 +cv-panel 0:2669e1f6d55c 1.07 0.15 professionaltrack +cv-panel 0:4f17e3d7d6f4 0.87 0.15 java17platformdeep-dive:records, +cv-panel 0:9e6154a3b625 0.89 0.15 matching,virtualthreads. +cv-panel 0:7b476727faf3 1.57 0.15 additional +cv-panel 0:3f88eb4c530c 1.15 0.15 languages:english(fluent),german +cv-panel 0:5d276fee8c17 1.17 0.15 (basic) +cv-panel 0:ec9d3622395e 1.39 0.15 workeligibility:eligibletoworkin +cv-panel 0:d05b8b335e96 1.21 0.15 opensource:maintainerofgraphcomp +cv-panel 0:2f3b4176123d 1.23 0.15 contributortopdfboxissuetriage. +cv-panel 0:1ae173b42166 1.25 0.15 speaking:jvmsummit2024,devoxxuk2 +cv-panel 0:309255ca6a36 1.27 0.15 declarativedocumentlayout. +cv-panel 0:53e5e7c5a884 0.69 0.16 experience +cv-panel 0:99b44abc1b3e 0.47 0.16 seniorplatformengineer-2024-pres +cv-panel 0:f890faef907f 0.49 0.16 northwindsystems +cv-panel 0:e32ca827bfd5 0.29 0.16 ledthereusabledocument-generatio +cv-panel 0:675f8862fdda 0.31 0.16 hiring,andreportingflowsacross8p +cv-panel 0:93d48fc85054 0.33 0.16 templatemaintenancetimeby70%byre +cv-panel 0:e7f09e2ba7d2 0.35 0.16 scriptsinfavourofonecanonicaleng +cv-panel 0:ded138c59d03 0.57 0.16 softwareengineer-2021-2024 +cv-panel 0:998c1a985022 0.59 0.16 brightleaflabs +cv-panel 0:0ed66ac9265d 0.39 0.16 builtbackendservicesandproductio +cv-panel 0:17c4ef49d4e6 0.41 0.16 pipelinesprocessing2m+documentsp +cv-panel 0:a7dd3c5be76b 0.43 0.16 migrationfromitexttoacustomlayou +cv-panel 0:a35401d8bcad 0.45 0.16 licensingriskandcuttingp99render +cv-panel 0:649d2d9d10d0 0.47 0.16 380ms. +cv-panel 0:019bbdc8d0bb 0.69 0.16 backendengineer-2019-2021 +cv-panel 0:ef148f221e31 0.71 0.16 helixprintco +cv-panel 0:09cc06a649eb 0.51 0.16 maintainedahigh-volumeinvoice-pr +cv-panel 0:090e2184c17b 0.53 0.16 pdfs/year)andauthoredthecomplian +cv-panel 0:6f071fdf7529 0.55 0.16 gatedeverytemplatechange. +cv-panel 0:2577c0f557b2 1.23 0.16 projects +cv-panel 0:b2b029995203 1.01 0.16 •graphcompose(java21,pdfbox,mave +cv-panel 0:81c8132f9792 0.89 0.16 systems.(opensource) +cv-panel 0:753f46e4e01b 0.91 0.16 •templatestudio(kotlin,composede +cv-panel 0:6eb35b5b9a91 0.93 0.16 diff) +cv-panel 0:d919bd2d50b6 0.95 0.16 internaltoolforevaluatingcv,prop +cv-panel 0:245b9e56b9de 0.97 0.16 across14designpresets.pngdiffing +cv-panel 0:6bc2807453c6 0.99 0.16 baselinefreezing. +cv-panel 0:25cdca2beb8b 1.21 0.16 •layoutlint(java21,javaparser,sp +cv-panel 0:30e034b9c7b2 1.03 0.16 staticanalyserthatflagsfragileau +cv-panel 0:e7ad19d64668 1.05 0.16 nestedrows,untypedoffsets,implic +cv-panel 0:95ac1a62c76f 1.07 0.16 theyshiptoproduction. +cv-panel 0:fb1927f88597 1.29 0.16 •chromeforge(java,graphcompose,p +cv-panel 0:bb865a4ccac1 1.11 0.16 editorial-magazinedocumenttoolki +cv-panel 0:8a31ccd889ee 1.13 0.16 cinematiccovers,pullquotes,multi +cv-panel 0:fe63fe18585a 1.15 0.16 callouts. cv-professional_sidebar 0:093e7d5fdbaa -0.23 0.10 contact cv-professional_sidebar 0:7f459725e1f6 -0.03 -0.04 +12345678900 cv-professional_sidebar 0:52bf11c1afe0 -0.08 -0.04 your.email@example.com @@ -1175,17 +1175,17 @@ cv-serif_headline 0:2198cdea3aba 0.44 0.10 devsphere|newyork,ny cv-serif_headline 0:173ed9f7b6b1 0.45 0.10 •assistedindevelopingandmaintain cv-serif_headline 0:0a1fbe0c94d9 0.45 0.10 •wroteunitandintegrationteststoe cv-serif_headline 0:bd5eec545fa8 0.46 0.10 •participatedinagileceremoniesan -cv-serif_headline 0:2577c0f557b2 0.54 0.13 projects -cv-serif_headline 0:c03ade0f8985 0.59 0.13 e-commerceplatform -cv-serif_headline 0:f726495cb8e6 0.59 0.13 java,springboot,react,postgresql -cv-serif_headline 0:09271909c2c5 0.36 0.13 developedafull-stacke-commerce -cv-serif_headline 0:a395647dca6c 0.36 0.13 platformwithuserauthentication,p -cv-serif_headline 0:19ed6c29c718 0.36 0.13 catalog,cart,andpaymentintegrati -cv-serif_headline 0:1c1e5cfc5031 0.59 0.11 taskmanagementapi -cv-serif_headline 0:4e8f2a166cfe 0.59 0.11 java,springboot,mongodb,docker -cv-serif_headline 0:793437bcb507 0.36 0.11 builtarestfulapifortaskmanagemen -cv-serif_headline 0:47492456be77 0.36 0.11 withrole-basedaccess,real-time -cv-serif_headline 0:7d9a1a98ac6c 0.36 0.11 updates,anddockerizeddeployment. +cv-serif_headline 0:2577c0f557b2 0.44 0.13 projects +cv-serif_headline 0:c03ade0f8985 0.49 0.13 e-commerceplatform +cv-serif_headline 0:f726495cb8e6 0.49 0.13 java,springboot,react,postgresql +cv-serif_headline 0:09271909c2c5 0.26 0.13 developedafull-stacke-commerce +cv-serif_headline 0:a395647dca6c 0.26 0.13 platformwithuserauthentication,p +cv-serif_headline 0:19ed6c29c718 0.26 0.13 catalog,cart,andpaymentintegrati +cv-serif_headline 0:1c1e5cfc5031 0.49 0.11 taskmanagementapi +cv-serif_headline 0:4e8f2a166cfe 0.49 0.11 java,springboot,mongodb,docker +cv-serif_headline 0:793437bcb507 0.26 0.11 builtarestfulapifortaskmanagemen +cv-serif_headline 0:47492456be77 0.26 0.11 withrole-basedaccess,real-time +cv-serif_headline 0:7d9a1a98ac6c 0.26 0.11 updates,anddockerizeddeployment. cv-serif_headline 0:68bf0109c6f8 0.00 0.09 education cv-serif_headline 0:6a75b3a10877 0.07 0.14 m.s.incomputerscience cv-serif_headline 0:d244381bfb58 0.10 0.14 newyorkuniversity @@ -1584,6 +1584,7 @@ cv-timeline_minimal 0:54b7bb3a12a0 -0.45 0.10 jmh):declarativejavapdflayouteng cv-timeline_minimal 0:83ee0a75c2d4 -0.45 0.10 semanticdsl,slot-basedtemplates, cv-timeline_minimal 0:235802baf524 -0.45 0.10 snapshottesting.powersproduction cv-timeline_minimal 0:44925c9e42ee -0.45 0.10 invoice/proposalpipelinesforhiri +cv-timeline_minimal 0:de1af4623873 -0.45 0.10 andbillingsystems.(opensource) cv-timeline_minimal 0:ae7902eee4b2 -0.45 0.10 templatestudio(kotlin,composedes cv-timeline_minimal 0:f15436034237 -0.45 0.10 pdfboxpngdiff):internaltoolfor cv-timeline_minimal 0:24a195694090 -0.45 0.10 evaluatingcv,proposal,andinvoice @@ -1660,49 +1661,49 @@ cv-violet_grid 0:caf9f906b16a -0.22 -0.45 documentation cv-violet_grid 0:f9d35d43770d -0.24 0.10 tools cv-violet_grid 0:5cb2b3b6143c -0.18 0.10 figmafigjamadobexdsketchmironoti cv-violet_grid 0:53e5e7c5a884 -0.20 0.10 experience -cv-violet_grid 0:5a0774260e0c -0.08 0.10 2022-present -cv-violet_grid 0:204f460767ff -0.12 0.02 seniorux/uidesigner|novafin(fint -cv-violet_grid 0:318bba211bdc -0.07 -0.23 sanfrancisco,ca -cv-violet_grid 0:318bba211bdc#1 -0.15 -0.23 sanfrancisco,ca -cv-violet_grid 0:3883e88c63c3 -0.08 0.05 ledend-to-enddesignforapersonalf -cv-violet_grid 0:ccc00663f089 -0.10 0.05 conducteduserresearch,builtperso -cv-violet_grid 0:7d0f908c7e5f -0.12 0.05 designedwireframes,prototypes,an -cv-violet_grid 0:9b57c4a85aad -0.13 0.05 establishedandmaintainedascalabl -cv-violet_grid 0:6894eafb99c2 -0.15 0.05 collaboratedwithproductmanagers, -cv-violet_grid 0:01e4455cec51 -0.16 0.10 2020-2022 -cv-violet_grid 0:24d722f0cfbe -0.20 0.02 uxdesigner|brighthealth(healthte -cv-violet_grid 0:530707fb0897 -0.16 0.05 redesignedpatientportalexperienc -cv-violet_grid 0:b2e27a1d9270 -0.18 0.05 plannedandfacilitatedusabilityte -cv-violet_grid 0:ab80a52d70fe -0.20 0.05 partneredwithengineerstoensurefe -cv-violet_grid 0:11cbf615189b -0.21 0.05 createdreusablecomponentsandstyl -cv-violet_grid 0:7e5081a3ed48 -0.22 0.10 2018-2020 -cv-violet_grid 0:73f7bbf7cd60 -0.26 0.02 juniorux/uidesigner|lumendigital -cv-violet_grid 0:c6b06045332f -0.21 -0.17 austin,tx -cv-violet_grid 0:5ea8234925c5 -0.22 0.05 supporteddiscoveryworkshops,user -cv-violet_grid 0:46f00c76528c -0.24 0.05 designedresponsivewebsitesandlan -cv-violet_grid 0:f3cea36a9d83 -0.26 0.05 collaboratedwithcopywritersandde -cv-violet_grid 0:d94eccbb1fbe -0.29 0.10 selectedprojects -cv-violet_grid 0:45dc8bf81211 -0.34 0.08 novafinmobileapp|personalfinance -cv-violet_grid 0:d398b29d3dbb -0.29 0.61 2023 -cv-violet_grid 0:e66c1ce573d3 -0.43 0.08 ledux/uidesignforbudgeting,goalt -cv-violet_grid 0:0ed8829e68d0 -0.43 0.08 thatinformedasimplifiednavigatio -cv-violet_grid 0:ee9bd17ebccf -0.43 0.08 22%increaseinweeklyactiveusers. -cv-violet_grid 0:28b4603d784a -0.35 0.08 brighthealthpatientportal|health -cv-violet_grid 0:1bea20e1df19 -0.30 0.61 2021 -cv-violet_grid 0:999ddb26bed6 -0.44 0.08 redesignedkeypatientflowsincludi -cv-violet_grid 0:073d15633c0b -0.44 0.08 systemandcomponentlibraryusedacr -cv-violet_grid 0:68bf0109c6f8 -0.19 0.10 education -cv-violet_grid 0:6cb574fa10b6 -0.19 0.07 languages -cv-violet_grid 0:0cf7506cf94a -0.12 0.10 bacheloroffineartsingraphicdesig -cv-violet_grid 0:00ab7a6aa5f1 -0.11 0.10 californiacollegeofthearts -cv-violet_grid 0:7e2c21bb41db -0.12 0.10 sanfrancisco,ca|2014-2018 -cv-violet_grid 0:b6234d2ea0d6 -1.47 0.02 english -cv-violet_grid 0:bef32d2c315a -1.48 -0.03 native -cv-violet_grid 0:bef32d2c315a#1 -1.44 -0.03 native -cv-violet_grid 0:9c9b13446cd9 -1.44 0.02 spanish -cv-violet_grid 0:e35242c809c8 -1.41 0.02 portuguese -cv-violet_grid 0:c5d1de4964d6 -1.41 -0.03 conversational -cv-violet_grid 0:1de4fede4f63 -1.16 -0.17 idesignwithempathy,iteratewithpu +cv-violet_grid 0:5a0774260e0c -0.18 0.10 2022-present +cv-violet_grid 0:204f460767ff -0.22 0.02 seniorux/uidesigner|novafin(fint +cv-violet_grid 0:318bba211bdc -0.17 -0.23 sanfrancisco,ca +cv-violet_grid 0:318bba211bdc#1 -0.25 -0.23 sanfrancisco,ca +cv-violet_grid 0:3883e88c63c3 -0.18 0.05 ledend-to-enddesignforapersonalf +cv-violet_grid 0:ccc00663f089 -0.20 0.05 conducteduserresearch,builtperso +cv-violet_grid 0:7d0f908c7e5f -0.22 0.05 designedwireframes,prototypes,an +cv-violet_grid 0:9b57c4a85aad -0.23 0.05 establishedandmaintainedascalabl +cv-violet_grid 0:6894eafb99c2 -0.25 0.05 collaboratedwithproductmanagers, +cv-violet_grid 0:01e4455cec51 -0.26 0.10 2020-2022 +cv-violet_grid 0:24d722f0cfbe -0.30 0.02 uxdesigner|brighthealth(healthte +cv-violet_grid 0:530707fb0897 -0.26 0.05 redesignedpatientportalexperienc +cv-violet_grid 0:b2e27a1d9270 -0.28 0.05 plannedandfacilitatedusabilityte +cv-violet_grid 0:ab80a52d70fe -0.30 0.05 partneredwithengineerstoensurefe +cv-violet_grid 0:11cbf615189b -0.31 0.05 createdreusablecomponentsandstyl +cv-violet_grid 0:7e5081a3ed48 -0.32 0.10 2018-2020 +cv-violet_grid 0:73f7bbf7cd60 -0.36 0.02 juniorux/uidesigner|lumendigital +cv-violet_grid 0:c6b06045332f -0.31 -0.17 austin,tx +cv-violet_grid 0:5ea8234925c5 -0.32 0.05 supporteddiscoveryworkshops,user +cv-violet_grid 0:46f00c76528c -0.34 0.05 designedresponsivewebsitesandlan +cv-violet_grid 0:f3cea36a9d83 -0.36 0.05 collaboratedwithcopywritersandde +cv-violet_grid 0:d94eccbb1fbe -0.39 0.10 selectedprojects +cv-violet_grid 0:45dc8bf81211 -0.44 0.08 novafinmobileapp|personalfinance +cv-violet_grid 0:d398b29d3dbb -0.39 0.61 2023 +cv-violet_grid 0:e66c1ce573d3 -0.53 0.08 ledux/uidesignforbudgeting,goalt +cv-violet_grid 0:0ed8829e68d0 -0.53 0.08 thatinformedasimplifiednavigatio +cv-violet_grid 0:ee9bd17ebccf -0.53 0.08 22%increaseinweeklyactiveusers. +cv-violet_grid 0:28b4603d784a -0.45 0.08 brighthealthpatientportal|health +cv-violet_grid 0:1bea20e1df19 -0.40 0.61 2021 +cv-violet_grid 0:999ddb26bed6 -0.54 0.08 redesignedkeypatientflowsincludi +cv-violet_grid 0:073d15633c0b -0.54 0.08 systemandcomponentlibraryusedacr +cv-violet_grid 0:68bf0109c6f8 -0.29 0.10 education +cv-violet_grid 0:6cb574fa10b6 -0.29 0.07 languages +cv-violet_grid 0:0cf7506cf94a -0.22 0.10 bacheloroffineartsingraphicdesig +cv-violet_grid 0:00ab7a6aa5f1 -0.21 0.10 californiacollegeofthearts +cv-violet_grid 0:7e2c21bb41db -0.22 0.10 sanfrancisco,ca|2014-2018 +cv-violet_grid 0:b6234d2ea0d6 -1.57 0.02 english +cv-violet_grid 0:bef32d2c315a -1.58 -0.03 native +cv-violet_grid 0:bef32d2c315a#1 -1.54 -0.03 native +cv-violet_grid 0:9c9b13446cd9 -1.54 0.02 spanish +cv-violet_grid 0:e35242c809c8 -1.51 0.02 portuguese +cv-violet_grid 0:c5d1de4964d6 -1.51 -0.03 conversational +cv-violet_grid 0:1de4fede4f63 -1.26 -0.17 idesignwithempathy,iteratewithpu invoice-classic 0:c26c22b94338 0.49 0.10 graphcomposestudio invoice-classic 0:c26c22b94338#1 0.30 0.06 graphcomposestudio invoice-classic 0:2a08ce5567fb 0.35 0.10 18layoutstreet @@ -2545,18 +2546,18 @@ invoice-luma_studio_long 2:bc6d215b63ee 0.01 1.24 page3of3 invoice-merchant 0:0dffa3b5d008 -0.01 0.10 coastline invoice-merchant 0:52d6e3de4fa0 0.08 0.85 invoice invoice-merchant 0:9422e2aeb800 0.08 0.08 coastlinecommerceinc. -invoice-merchant 0:9422e2aeb800#1 0.20 0.53 coastlinecommerceinc. +invoice-merchant 0:9422e2aeb800#1 0.10 0.53 coastlinecommerceinc. invoice-merchant 0:8bb83c0c3efb 0.10 0.08 150elginstreet,8thfloor invoice-merchant 0:cf0df3462e70 0.09 0.08 ottawa,onk2p1l4 invoice-merchant 0:408c7c5887a0 0.09 0.08 canada invoice-merchant 0:0d9b94d29fc9 0.01 0.27 www.coastline.example invoice-merchant 0:76957649b8a8 -0.02 0.27 billing@coastline.example -invoice-merchant 0:76957649b8a8#1 0.23 0.53 billing@coastline.example +invoice-merchant 0:76957649b8a8#1 0.13 0.53 billing@coastline.example invoice-merchant 0:0b44bf19dd44 -0.05 0.27 +1613-555-0142 invoice-merchant 0:884004f21362 -0.03 0.08 vatid:ca8139020285rt0001 invoice-merchant 0:6282391a4cc1 0.23 0.09 invoicenumber: invoice-merchant 0:a6e01b979f55 0.23 0.08 inv-2026-000789 -invoice-merchant 0:a6e01b979f55#1 0.23 0.53 inv-2026-000789 +invoice-merchant 0:a6e01b979f55#1 0.13 0.53 inv-2026-000789 invoice-merchant 0:8d05f5d55191 0.20 0.09 invoicedate: invoice-merchant 0:dc9696f61d36 0.20 0.08 27may2026 invoice-merchant 0:0e0fb0fc0939 0.18 0.09 duedate: @@ -2607,23 +2608,23 @@ invoice-merchant 0:0036ebf2cfb2 -0.12 0.07 prioritysupport invoice-merchant 0:6bfa3f8e9308 -0.17 0.07 24/7support invoice-merchant 0:7f0f70e643bc -0.16 -0.26 included invoice-merchant 0:3c7ade679fdf 0.08 0.51 paymentdetails -invoice-merchant 0:944d398aea60 0.20 0.55 bankname: -invoice-merchant 0:d6c3cea2e943 0.20 0.53 harbourbankofcanada -invoice-merchant 0:0ecb5847ffa7 0.20 0.55 accountname: -invoice-merchant 0:6b4894c28363 0.21 0.55 accountnumber: -invoice-merchant 0:ca2ea6319cc8 0.21 0.53 1001-4267-153 -invoice-merchant 0:555043320c0c 0.21 0.55 swiftcode: -invoice-merchant 0:922f5f70c123 0.21 0.53 hrbrcat2 -invoice-merchant 0:f1b1597830d6 0.21 0.55 institutionnumber: -invoice-merchant 0:88c0413bfef1 0.21 0.53 003 -invoice-merchant 0:e47c9313aced 0.22 0.55 transitnumber: -invoice-merchant 0:fec334e6bf8c 0.22 0.53 00016 -invoice-merchant 0:4f657c67e41a 0.22 0.55 accounttype: -invoice-merchant 0:b8b8acdf702e 0.22 0.53 cadaccount -invoice-merchant 0:fa0fbe194b51 0.23 0.55 remittanceemail: -invoice-merchant 0:c608665436db 0.23 0.55 reference: -invoice-merchant 0:1b0fdc20ced4 0.16 0.55 pleaseincludetheinvoicenumber -invoice-merchant 0:cfdf1faf410b 0.14 0.55 inyourpaymentreference. +invoice-merchant 0:944d398aea60 0.10 0.55 bankname: +invoice-merchant 0:d6c3cea2e943 0.10 0.53 harbourbankofcanada +invoice-merchant 0:0ecb5847ffa7 0.10 0.55 accountname: +invoice-merchant 0:6b4894c28363 0.11 0.55 accountnumber: +invoice-merchant 0:ca2ea6319cc8 0.11 0.53 1001-4267-153 +invoice-merchant 0:555043320c0c 0.11 0.55 swiftcode: +invoice-merchant 0:922f5f70c123 0.11 0.53 hrbrcat2 +invoice-merchant 0:f1b1597830d6 0.11 0.55 institutionnumber: +invoice-merchant 0:88c0413bfef1 0.11 0.53 003 +invoice-merchant 0:e47c9313aced 0.12 0.55 transitnumber: +invoice-merchant 0:fec334e6bf8c 0.12 0.53 00016 +invoice-merchant 0:4f657c67e41a 0.12 0.55 accounttype: +invoice-merchant 0:b8b8acdf702e 0.12 0.53 cadaccount +invoice-merchant 0:fa0fbe194b51 0.13 0.55 remittanceemail: +invoice-merchant 0:c608665436db 0.13 0.55 reference: +invoice-merchant 0:1b0fdc20ced4 0.06 0.55 pleaseincludetheinvoicenumber +invoice-merchant 0:cfdf1faf410b 0.04 0.55 inyourpaymentreference. invoice-merchant 0:d6577e95efba 0.09 0.10 subtotal invoice-merchant 0:30d16b02fd3e 0.16 0.93 444.00 invoice-merchant 0:2ee4d3de4ddf 0.11 0.10 tax(0%) @@ -2726,8 +2727,8 @@ invoice-metered 0:e50d8a0ea599 -0.10 0.70 gbp42.94 invoice-metered 0:57a66d21eb1b -0.23 0.14 totaldue invoice-metered 0:f207312dff2f -0.30 -0.05 gbp257.65 invoice-metered 0:b0553f008513 -0.14 0.11 paymentdueby -invoice-metered 0:e60e7ef06ccc -0.96 0.10 thankyouforrunningonnorthwindclo -invoice-metered 0:34ea2ec3fe72 -0.96 0.10 forbillingandaccountsupport,visi +invoice-metered 0:e60e7ef06ccc -0.01 0.10 thankyouforrunningonnorthwindclo +invoice-metered 0:34ea2ec3fe72 -0.01 0.10 forbillingandaccountsupport,visi invoice-metered 0:e28672d64882 -0.04 0.12 northwindcloudservicesltd.isasub invoice-metered 0:985e43c2de34 -0.04 0.12 120riversideway,bristol,bs16qt,u invoice-metered 0:7b14b8d2c5c4 -0.04 0.16 page1of1 @@ -2951,7 +2952,7 @@ invoice-obsidian 0:07f15cde5b18 0.14 0.09 kestrel invoice-obsidian 0:52d6e3de4fa0 0.12 0.09 invoice invoice-obsidian 0:5d1d1b79af09 0.02 0.09 invoicenumber invoice-obsidian 0:3e62d1fbe5ec 0.06 0.09 inv-2026-1048 -invoice-obsidian 0:3e62d1fbe5ec#1 -0.56 0.08 inv-2026-1048 +invoice-obsidian 0:3e62d1fbe5ec#1 0.49 0.08 inv-2026-1048 invoice-obsidian 0:8feaf8016bab 0.02 0.09 issuedate invoice-obsidian 0:4d49cb78b810 0.02 0.16 27august2026 invoice-obsidian 0:ac10f8c16320 -0.05 0.09 duedate @@ -2962,76 +2963,76 @@ invoice-obsidian 0:466e5b9cd57f -0.19 0.09 currency invoice-obsidian 0:54f8e1b3fe44 -0.19 0.54 gbp invoice-obsidian 0:75857a458999 -0.26 0.10 from invoice-obsidian 0:7d7385ecfbd9 -0.29 0.07 kestrelbusiness -invoice-obsidian 0:7d7385ecfbd9#1 -0.53 0.08 kestrelbusiness -invoice-obsidian 0:7d7385ecfbd9#2 -0.22 -0.55 kestrelbusiness +invoice-obsidian 0:7d7385ecfbd9#1 0.52 0.08 kestrelbusiness +invoice-obsidian 0:7d7385ecfbd9#2 0.48 -0.55 kestrelbusiness invoice-obsidian 0:5f51304df361 -0.27 0.07 7harboursidewalk invoice-obsidian 0:895a6b59f677 -0.29 0.07 bristolbs15ty invoice-obsidian 0:2474519f77a9 -0.29 0.07 unitedkingdom invoice-obsidian 0:2474519f77a9#1 -0.29 0.08 unitedkingdom invoice-obsidian 0:70ec69d2102f -0.31 0.07 ar@kestrel.example -invoice-obsidian 0:70ec69d2102f#1 -0.22 -0.74 ar@kestrel.example +invoice-obsidian 0:70ec69d2102f#1 0.48 -0.74 ar@kestrel.example invoice-obsidian 0:aeba3a7b3598 -0.26 0.11 billto invoice-obsidian 0:7bfc2b791f41 -0.29 0.08 northlineconsultingltd invoice-obsidian 0:13dd937d2fe6 -0.27 0.08 21jubileeway invoice-obsidian 0:f9bab6a0b45b -0.29 0.08 londonse13ss -invoice-obsidian 0:c9046f7a37ad -1.90 0.40 description -invoice-obsidian 0:32e8369a9c4f -1.90 0.25 qty -invoice-obsidian 0:d1062d072acd -1.90 -0.25 unitprice -invoice-obsidian 0:a52611c9261b -1.90 -0.35 vat(20%) -invoice-obsidian 0:a52611c9261b#1 -0.17 0.11 vat(20%) -invoice-obsidian 0:cf38d95c9c6b -1.90 -0.08 amount -invoice-obsidian 0:15345cbad705 -0.52 0.40 subscriptionsetup -invoice-obsidian 0:5100476d46bb -0.52 0.40 one-offaccountandworkspacesetup -invoice-obsidian 0:507f9f133059 -0.56 -0.12 £150.00 -invoice-obsidian 0:893d7480f763 -0.56 -0.07 £30.00 -invoice-obsidian 0:893d7480f763#1 -0.88 -0.06 £30.00 -invoice-obsidian 0:629184210581 -0.56 -0.11 £180.00 -invoice-obsidian 0:3e8060178bc4 -0.56 0.40 internationalpaymentsupport -invoice-obsidian 0:33e4ab51097e -0.56 0.40 monthlysupportforcross-borderpay -invoice-obsidian 0:96d6b62c061d -0.60 -0.12 £250.00 -invoice-obsidian 0:70d5b1312085 -0.60 -0.07 £50.00 -invoice-obsidian 0:d86642b21e53 -0.60 -0.11 £300.00 -invoice-obsidian 0:9399cf3b221a -0.61 0.40 expensemanagementintegration -invoice-obsidian 0:da2890c99f7a -0.61 0.40 apiaccessandintegration -invoice-obsidian 0:372ba7238228 -0.64 -0.12 £200.00 -invoice-obsidian 0:05c6a4f7132f -0.64 -0.07 £40.00 -invoice-obsidian 0:853580239989 -0.64 -0.11 £240.00 -invoice-obsidian 0:ba80be228223 -0.65 0.40 virtualcards -invoice-obsidian 0:eae2564ef311 -0.65 0.40 50virtualcards -invoice-obsidian 0:cf02270203a4 -0.69 -0.12 £100.00 -invoice-obsidian 0:33b5fc913817 -0.69 -0.07 £20.00 -invoice-obsidian 0:8aec54fdb1a1 -0.69 -0.11 £120.00 -invoice-obsidian 0:cc29e90932c5 -0.84 0.40 businessaccountmaintenance -invoice-obsidian 0:f1254de1a1d4 -0.84 0.40 monthlyaccountmaintenancefee -invoice-obsidian 0:8bf9ac7b27bd -0.88 0.03 £6.00 -invoice-obsidian 0:bff295cd3f97 -0.88 -0.06 £36.00 -invoice-obsidian 0:d6577e95efba -0.14 0.11 subtotal -invoice-obsidian 0:4595e1b34cb1 -0.15 0.68 £730.00 -invoice-obsidian 0:eafa82a0eadf -0.19 0.68 £146.00 -invoice-obsidian 0:57a66d21eb1b -0.27 0.11 totaldue -invoice-obsidian 0:ad3ba615a506 -0.29 -0.54 £876.00 -invoice-obsidian 0:ab5aa97074c4 -0.48 0.08 notes -invoice-obsidian 0:0956d8d0441d 0.14 0.08 thankyouforchoosingkestrelbusine -invoice-obsidian 0:0b4d6f0e8783 0.14 0.08 thisinvoicecoversservicesandfeat -invoice-obsidian 0:02e483554647 0.15 0.08 toyourbusinessasofthedateofissue -invoice-obsidian 0:b439106fc5a1 0.16 0.08 ifyouhaveanyquestionsaboutthisin -invoice-obsidian 0:877ac656a147 0.17 0.08 pleasecontactusatar@kestrel.exam -invoice-obsidian 0:3c7ade679fdf -0.48 0.09 paymentdetails -invoice-obsidian 0:473fbeedb47c -1.00 0.11 pleasepaybybanktransfer -invoice-obsidian 0:59f2b74175d7 -0.99 0.11 totheaccountbelow. -invoice-obsidian 0:811f691f5582 -0.47 0.11 payee -invoice-obsidian 0:10aeacde20ff -0.48 0.11 sortcode -invoice-obsidian 0:a748c443f622 -0.54 0.08 04-00-75 -invoice-obsidian 0:f92a9c925024 -0.49 0.11 accountnumber -invoice-obsidian 0:ef797c8118f0 -0.55 0.08 12345678 -invoice-obsidian 0:52367a6622b1 -0.50 0.11 reference -invoice-obsidian 0:7c6ab37d83ef -0.22 0.08 thankyouforyourbusiness. -invoice-obsidian 0:a97667f07d1b -0.23 0.08 paymentisdueby10september2026. +invoice-obsidian 0:c9046f7a37ad -1.60 0.40 description +invoice-obsidian 0:32e8369a9c4f -1.60 0.25 qty +invoice-obsidian 0:d1062d072acd -1.60 -0.25 unitprice +invoice-obsidian 0:a52611c9261b -1.60 -0.35 vat(20%) +invoice-obsidian 0:a52611c9261b#1 0.48 0.11 vat(20%) +invoice-obsidian 0:cf38d95c9c6b -1.60 -0.08 amount +invoice-obsidian 0:15345cbad705 -0.22 0.40 subscriptionsetup +invoice-obsidian 0:5100476d46bb -0.22 0.40 one-offaccountandworkspacesetup +invoice-obsidian 0:507f9f133059 -0.26 -0.12 £150.00 +invoice-obsidian 0:893d7480f763 -0.26 -0.07 £30.00 +invoice-obsidian 0:893d7480f763#1 -0.58 -0.06 £30.00 +invoice-obsidian 0:629184210581 -0.26 -0.11 £180.00 +invoice-obsidian 0:3e8060178bc4 -0.26 0.40 internationalpaymentsupport +invoice-obsidian 0:33e4ab51097e -0.26 0.40 monthlysupportforcross-borderpay +invoice-obsidian 0:96d6b62c061d -0.30 -0.12 £250.00 +invoice-obsidian 0:70d5b1312085 -0.30 -0.07 £50.00 +invoice-obsidian 0:d86642b21e53 -0.30 -0.11 £300.00 +invoice-obsidian 0:9399cf3b221a -0.31 0.40 expensemanagementintegration +invoice-obsidian 0:da2890c99f7a -0.31 0.40 apiaccessandintegration +invoice-obsidian 0:372ba7238228 -0.34 -0.12 £200.00 +invoice-obsidian 0:05c6a4f7132f -0.34 -0.07 £40.00 +invoice-obsidian 0:853580239989 -0.34 -0.11 £240.00 +invoice-obsidian 0:ba80be228223 -0.35 0.40 virtualcards +invoice-obsidian 0:eae2564ef311 -0.35 0.40 50virtualcards +invoice-obsidian 0:cf02270203a4 -0.39 -0.12 £100.00 +invoice-obsidian 0:33b5fc913817 -0.39 -0.07 £20.00 +invoice-obsidian 0:8aec54fdb1a1 -0.39 -0.11 £120.00 +invoice-obsidian 0:cc29e90932c5 -0.54 0.40 businessaccountmaintenance +invoice-obsidian 0:f1254de1a1d4 -0.54 0.40 monthlyaccountmaintenancefee +invoice-obsidian 0:8bf9ac7b27bd -0.58 0.03 £6.00 +invoice-obsidian 0:bff295cd3f97 -0.58 -0.06 £36.00 +invoice-obsidian 0:d6577e95efba 0.51 0.11 subtotal +invoice-obsidian 0:4595e1b34cb1 0.50 0.68 £730.00 +invoice-obsidian 0:eafa82a0eadf 0.46 0.68 £146.00 +invoice-obsidian 0:57a66d21eb1b 0.38 0.11 totaldue +invoice-obsidian 0:ad3ba615a506 0.36 -0.54 £876.00 +invoice-obsidian 0:ab5aa97074c4 0.57 0.08 notes +invoice-obsidian 0:0956d8d0441d 1.19 0.08 thankyouforchoosingkestrelbusine +invoice-obsidian 0:0b4d6f0e8783 1.19 0.08 thisinvoicecoversservicesandfeat +invoice-obsidian 0:02e483554647 1.20 0.08 toyourbusinessasofthedateofissue +invoice-obsidian 0:b439106fc5a1 1.21 0.08 ifyouhaveanyquestionsaboutthisin +invoice-obsidian 0:877ac656a147 1.22 0.08 pleasecontactusatar@kestrel.exam +invoice-obsidian 0:3c7ade679fdf 0.57 0.09 paymentdetails +invoice-obsidian 0:473fbeedb47c 0.05 0.11 pleasepaybybanktransfer +invoice-obsidian 0:59f2b74175d7 0.06 0.11 totheaccountbelow. +invoice-obsidian 0:811f691f5582 0.58 0.11 payee +invoice-obsidian 0:10aeacde20ff 0.57 0.11 sortcode +invoice-obsidian 0:a748c443f622 0.51 0.08 04-00-75 +invoice-obsidian 0:f92a9c925024 0.56 0.11 accountnumber +invoice-obsidian 0:ef797c8118f0 0.50 0.08 12345678 +invoice-obsidian 0:52367a6622b1 0.55 0.11 reference +invoice-obsidian 0:7c6ab37d83ef 0.48 0.08 thankyouforyourbusiness. +invoice-obsidian 0:a97667f07d1b 0.47 0.08 paymentisdueby10september2026. invoice-obsidian 0:7b14b8d2c5c4 -0.03 -0.41 page1of1 invoice-payments 0:b6c4ac412ac8 -0.02 0.10 meridian invoice-payments 0:52d6e3de4fa0 0.41 0.05 invoice invoice-payments 0:c0cc75b9cfdc -0.22 0.12 meridianpaymentsltd. -invoice-payments 0:c0cc75b9cfdc#1 -0.06 0.10 meridianpaymentsltd. +invoice-payments 0:c0cc75b9cfdc#1 -0.16 0.10 meridianpaymentsltd. invoice-payments 0:5eeaa101da6c -0.19 0.12 1harbourexchange invoice-payments 0:e3f6090f249b -0.23 0.12 canarywharf invoice-payments 0:1bb9adbf32ff -0.26 0.12 londone149ge @@ -3048,7 +3049,7 @@ invoice-payments 0:fb854bac39c8 -0.16 0.05 paymentterms invoice-payments 0:ac10f8c16320 -0.19 0.05 duedate invoice-payments 0:073c1634c496 -0.21 0.05 status invoice-payments 0:052ff4dff688 -0.04 -0.02 inv-2025-05-10472 -invoice-payments 0:052ff4dff688#1 -0.26 0.10 inv-2025-05-10472 +invoice-payments 0:052ff4dff688#1 -0.36 0.10 inv-2025-05-10472 invoice-payments 0:23a4c624cbda -0.01 -0.02 10may2025 invoice-payments 0:7b052c343b27 0.02 -0.02 1-30april2025 invoice-payments 0:018052c1dd59 0.04 -0.02 acct_4q8xtb2mkp @@ -3066,84 +3067,84 @@ invoice-payments 0:725a8f5062e7 0.13 0.00 shipto invoice-payments 0:9976f2392d8c 0.13 0.05 operationscentre invoice-payments 0:fc0e113402c7 0.10 0.05 7kingswaypark invoice-payments 0:a72c3f2308ed 0.07 0.05 leedsls126bd -invoice-payments 0:c9046f7a37ad 0.04 -0.23 description -invoice-payments 0:1a7b308d8df6 0.04 -0.32 quantity -invoice-payments 0:d1062d072acd 0.04 -0.29 unitprice -invoice-payments 0:7c512b48ba8a 0.04 -0.30 vat -invoice-payments 0:2da123241332 0.04 0.44 amount(gbp) -invoice-payments 0:3ab6c1099bcc 0.03 -0.28 subscriptionbilling -invoice-payments 0:c8e69cd6e074 0.17 -0.28 subscriptionmanagementandrecurri -invoice-payments 0:0c95c7ece1ce 0.01 -0.28 billing -invoice-payments 0:96d6b62c061d 0.00 -0.86 £250.00 -invoice-payments 0:96d6b62c061d#1 0.01 0.04 £250.00 -invoice-payments 0:dc934fe30a94 0.00 -0.44 20% -invoice-payments 0:dc934fe30a94#1 0.00 -0.44 20% -invoice-payments 0:dc934fe30a94#2 0.02 -0.44 20% -invoice-payments 0:dc934fe30a94#3 0.01 -0.44 20% -invoice-payments 0:dc934fe30a94#4 0.00 -0.44 20% -invoice-payments 0:dc934fe30a94#5 -0.01 -0.44 20% -invoice-payments 0:0a9acaea6477 0.03 -0.28 paymentprocessing -invoice-payments 0:b8a3c21545b4 0.17 -0.28 onlinecardpaymentsprocessing -invoice-payments 0:b42561a38a06 0.01 -0.28 (volumetier) -invoice-payments 0:351704ebff51 0.00 -1.05 £1,180.00 -invoice-payments 0:351704ebff51#1 0.01 0.12 £1,180.00 -invoice-payments 0:b3bc34f90a55 0.02 -0.28 fraudscreening -invoice-payments 0:ed051c6a1942 0.06 -0.28 advancedfraudscreeningandrules -invoice-payments 0:a0a787efd867 0.02 -0.86 £320.00 -invoice-payments 0:a0a787efd867#1 0.03 0.04 £320.00 -invoice-payments 0:34b75c1d0234 0.01 -0.28 companyformation -invoice-payments 0:bf45c494a8dc 0.05 -0.28 incorporationandcompliancefiling -invoice-payments 0:629184210581 0.01 -0.86 £180.00 -invoice-payments 0:629184210581#1 0.02 0.04 £180.00 -invoice-payments 0:9427a01801d2 0.00 -0.28 in-personterminals -invoice-payments 0:882be821cf2e 0.04 -0.28 terminalrentalandfirmwareupdates -invoice-payments 0:3c4459a5e4ec 0.00 -0.77 £39.00 -invoice-payments 0:5d16afda896e 0.01 0.04 £156.00 -invoice-payments 0:0036ebf2cfb2 -0.01 -0.28 prioritysupport -invoice-payments 0:7ef1d2ff5e3a 0.03 -0.28 namedengineer,one-hourresponse -invoice-payments 0:cf02270203a4 -0.01 -0.86 £100.00 -invoice-payments 0:cf02270203a4#1 0.00 0.04 £100.00 -invoice-payments 0:3c7ade679fdf -0.03 0.14 paymentdetails -invoice-payments 0:182748d2fece 0.01 0.15 bankname -invoice-payments 0:758f4a6f175f 0.02 0.15 accountname -invoice-payments 0:10aeacde20ff 0.03 0.15 sortcode -invoice-payments 0:f92a9c925024 0.04 0.15 accountnumber -invoice-payments 0:d53cd2cae33d 0.05 0.15 iban -invoice-payments 0:3f695692d5f1 0.06 0.15 swift/bic -invoice-payments 0:52367a6622b1 0.07 0.15 reference -invoice-payments 0:c66da4639881 -0.02 0.10 harbourbankplc -invoice-payments 0:2cd71c3c2603 -0.10 0.10 40-02-50 -invoice-payments 0:8fb8a81278c4 -0.14 0.10 71295408 -invoice-payments 0:48617b6d05d4 -0.18 0.10 gb29hrbk40025071295408 -invoice-payments 0:6929e6db6e1f -0.22 0.10 hrbkgb2l -invoice-payments 0:e4c4788968b2 0.06 -0.01 subtotal(excl.vat) -invoice-payments 0:7ed180496d4e 0.07 -0.01 vatat20% -invoice-payments 0:751cbab81a3a 0.10 0.29 £2,186.00 -invoice-payments 0:9a5256946abd 0.11 0.94 £437.20 -invoice-payments 0:57a66d21eb1b 0.05 -0.01 totaldue -invoice-payments 0:5eb0b17220fa 0.11 -0.01 dueby14june2025 -invoice-payments 0:30d896eb989f -0.15 -0.83 £2,623.20 -invoice-payments 0:ab5aa97074c4 0.26 0.14 notes -invoice-payments 0:241bcf576ac5 0.28 0.14 thankyouforyourbusiness.thisinvo -invoice-payments 0:f912ca46bf39 0.26 0.14 latepaymentmayincurinterestatthe -invoice-payments 0:73a09fec2c1a 0.30 0.10 paymentdueby14june2025 -invoice-payments 0:79df6c5bbc16 0.28 0.10 pleaseincludetheinvoicenumberasp -invoice-payments 0:28b3008f693b 0.24 0.01 questions?we'reheretohelp. -invoice-payments 0:5b88ed40a689 0.27 0.01 support@meridianpayments.example -invoice-payments 0:2e3891f6ba2f 0.28 0.01 39661900 +invoice-payments 0:c9046f7a37ad -0.06 -0.23 description +invoice-payments 0:1a7b308d8df6 -0.06 -0.32 quantity +invoice-payments 0:d1062d072acd -0.06 -0.29 unitprice +invoice-payments 0:7c512b48ba8a -0.06 -0.30 vat +invoice-payments 0:2da123241332 -0.06 0.44 amount(gbp) +invoice-payments 0:3ab6c1099bcc -0.07 -0.28 subscriptionbilling +invoice-payments 0:c8e69cd6e074 0.07 -0.28 subscriptionmanagementandrecurri +invoice-payments 0:0c95c7ece1ce -0.09 -0.28 billing +invoice-payments 0:96d6b62c061d -0.10 -0.86 £250.00 +invoice-payments 0:96d6b62c061d#1 -0.09 0.04 £250.00 +invoice-payments 0:dc934fe30a94 -0.10 -0.44 20% +invoice-payments 0:dc934fe30a94#1 -0.10 -0.44 20% +invoice-payments 0:dc934fe30a94#2 -0.08 -0.44 20% +invoice-payments 0:dc934fe30a94#3 -0.09 -0.44 20% +invoice-payments 0:dc934fe30a94#4 -0.10 -0.44 20% +invoice-payments 0:dc934fe30a94#5 -0.11 -0.44 20% +invoice-payments 0:0a9acaea6477 -0.07 -0.28 paymentprocessing +invoice-payments 0:b8a3c21545b4 0.07 -0.28 onlinecardpaymentsprocessing +invoice-payments 0:b42561a38a06 -0.09 -0.28 (volumetier) +invoice-payments 0:351704ebff51 -0.10 -1.05 £1,180.00 +invoice-payments 0:351704ebff51#1 -0.09 0.12 £1,180.00 +invoice-payments 0:b3bc34f90a55 -0.08 -0.28 fraudscreening +invoice-payments 0:ed051c6a1942 -0.04 -0.28 advancedfraudscreeningandrules +invoice-payments 0:a0a787efd867 -0.08 -0.86 £320.00 +invoice-payments 0:a0a787efd867#1 -0.07 0.04 £320.00 +invoice-payments 0:34b75c1d0234 -0.09 -0.28 companyformation +invoice-payments 0:bf45c494a8dc -0.05 -0.28 incorporationandcompliancefiling +invoice-payments 0:629184210581 -0.09 -0.86 £180.00 +invoice-payments 0:629184210581#1 -0.08 0.04 £180.00 +invoice-payments 0:9427a01801d2 -0.10 -0.28 in-personterminals +invoice-payments 0:882be821cf2e -0.06 -0.28 terminalrentalandfirmwareupdates +invoice-payments 0:3c4459a5e4ec -0.10 -0.77 £39.00 +invoice-payments 0:5d16afda896e -0.09 0.04 £156.00 +invoice-payments 0:0036ebf2cfb2 -0.11 -0.28 prioritysupport +invoice-payments 0:7ef1d2ff5e3a -0.07 -0.28 namedengineer,one-hourresponse +invoice-payments 0:cf02270203a4 -0.11 -0.86 £100.00 +invoice-payments 0:cf02270203a4#1 -0.10 0.04 £100.00 +invoice-payments 0:3c7ade679fdf -0.13 0.14 paymentdetails +invoice-payments 0:182748d2fece -0.09 0.15 bankname +invoice-payments 0:758f4a6f175f -0.08 0.15 accountname +invoice-payments 0:10aeacde20ff -0.07 0.15 sortcode +invoice-payments 0:f92a9c925024 -0.06 0.15 accountnumber +invoice-payments 0:d53cd2cae33d -0.05 0.15 iban +invoice-payments 0:3f695692d5f1 -0.04 0.15 swift/bic +invoice-payments 0:52367a6622b1 -0.03 0.15 reference +invoice-payments 0:c66da4639881 -0.12 0.10 harbourbankplc +invoice-payments 0:2cd71c3c2603 -0.20 0.10 40-02-50 +invoice-payments 0:8fb8a81278c4 -0.24 0.10 71295408 +invoice-payments 0:48617b6d05d4 -0.28 0.10 gb29hrbk40025071295408 +invoice-payments 0:6929e6db6e1f -0.32 0.10 hrbkgb2l +invoice-payments 0:e4c4788968b2 -0.04 -0.01 subtotal(excl.vat) +invoice-payments 0:7ed180496d4e -0.03 -0.01 vatat20% +invoice-payments 0:751cbab81a3a 0.00 0.29 £2,186.00 +invoice-payments 0:9a5256946abd 0.01 0.94 £437.20 +invoice-payments 0:57a66d21eb1b -0.05 -0.01 totaldue +invoice-payments 0:5eb0b17220fa 0.01 -0.01 dueby14june2025 +invoice-payments 0:30d896eb989f -0.25 -0.83 £2,623.20 +invoice-payments 0:ab5aa97074c4 0.06 0.14 notes +invoice-payments 0:241bcf576ac5 0.08 0.14 thankyouforyourbusiness.thisinvo +invoice-payments 0:f912ca46bf39 0.06 0.14 latepaymentmayincurinterestatthe +invoice-payments 0:73a09fec2c1a 0.10 0.10 paymentdueby14june2025 +invoice-payments 0:79df6c5bbc16 0.08 0.10 pleaseincludetheinvoicenumberasp +invoice-payments 0:28b3008f693b 0.04 0.01 questions?we'reheretohelp. +invoice-payments 0:5b88ed40a689 0.07 0.01 support@meridianpayments.example +invoice-payments 0:2e3891f6ba2f 0.08 0.01 39661900 invoice-payments 0:7b14b8d2c5c4 -0.04 -0.01 page1of1 invoice-platform 0:9817f28442bf 0.04 0.12 auroracloud invoice-platform 0:9817f28442bf#1 -0.56 0.14 auroracloud invoice-platform 0:52d6e3de4fa0 0.61 -0.21 invoice invoice-platform 0:1cf61cdc6464 0.06 0.13 auroracloudinc. -invoice-platform 0:1cf61cdc6464#1 -0.10 0.40 auroracloudinc. +invoice-platform 0:1cf61cdc6464#1 -0.20 0.40 auroracloudinc. invoice-platform 0:1cf61cdc6464#2 -0.53 0.30 auroracloudinc. invoice-platform 0:43315277b007 -0.40 0.13 500harbourstreet invoice-platform 0:d9065bfb8f59 -0.40 0.13 vancouver,bcv6c2w2 invoice-platform 0:408c7c5887a0 -0.41 0.13 canada invoice-platform 0:88a643f14708 0.18 0.21 aurora.example invoice-platform 0:f2cfc804c0f3 0.18 0.21 billing@aurora.example -invoice-platform 0:f2cfc804c0f3#1 -0.07 0.40 billing@aurora.example +invoice-platform 0:f2cfc804c0f3#1 -0.17 0.40 billing@aurora.example invoice-platform 0:799715f2b96e 0.19 0.21 +1604-555-0180 invoice-platform 0:719c55c7e988 -0.44 0.13 vatid:cabn842137755 invoice-platform 0:6282391a4cc1 -0.31 0.10 invoicenumber: @@ -3216,22 +3217,22 @@ invoice-platform 0:561b2814d3c0#1 -0.27 0.22 0.00 invoice-platform 0:efa8771baad9 -0.33 0.09 supportplan invoice-platform 0:9e81cd6e653a -0.30 0.09 standardresponse invoice-platform 0:13000a5d442c -0.25 0.35 paymentinformation -invoice-platform 0:944d398aea60 -0.11 0.44 bankname: -invoice-platform 0:d6c3cea2e943 -0.11 0.40 harbourbankofcanada -invoice-platform 0:0ecb5847ffa7 -0.10 0.44 accountname: -invoice-platform 0:6b4894c28363 -0.10 0.44 accountnumber: -invoice-platform 0:559c58c48948 -0.10 0.40 417802336 -invoice-platform 0:555043320c0c -0.09 0.44 swiftcode: -invoice-platform 0:5a986aa9e713 -0.09 0.40 hbcacat1 -invoice-platform 0:e47c9313aced -0.08 0.44 transitnumber: -invoice-platform 0:20b565bff5c3 -0.08 0.40 00812 -invoice-platform 0:f1b1597830d6 -0.08 0.44 institutionnumber: -invoice-platform 0:3c241d267414 -0.08 0.40 049 -invoice-platform 0:4f657c67e41a -0.07 0.44 accounttype: -invoice-platform 0:7522b6a6c098 -0.07 0.40 businesschequing -invoice-platform 0:fa0fbe194b51 -0.07 0.44 remittanceemail: -invoice-platform 0:b3ec04f337ed -0.17 0.35 includeyourbillingaccountid -invoice-platform 0:a11a3e122422 -0.18 0.35 onyourpaymentremittance. +invoice-platform 0:944d398aea60 -0.21 0.44 bankname: +invoice-platform 0:d6c3cea2e943 -0.21 0.40 harbourbankofcanada +invoice-platform 0:0ecb5847ffa7 -0.20 0.44 accountname: +invoice-platform 0:6b4894c28363 -0.20 0.44 accountnumber: +invoice-platform 0:559c58c48948 -0.20 0.40 417802336 +invoice-platform 0:555043320c0c -0.19 0.44 swiftcode: +invoice-platform 0:5a986aa9e713 -0.19 0.40 hbcacat1 +invoice-platform 0:e47c9313aced -0.18 0.44 transitnumber: +invoice-platform 0:20b565bff5c3 -0.18 0.40 00812 +invoice-platform 0:f1b1597830d6 -0.18 0.44 institutionnumber: +invoice-platform 0:3c241d267414 -0.18 0.40 049 +invoice-platform 0:4f657c67e41a -0.17 0.44 accounttype: +invoice-platform 0:7522b6a6c098 -0.17 0.40 businesschequing +invoice-platform 0:fa0fbe194b51 -0.17 0.44 remittanceemail: +invoice-platform 0:b3ec04f337ed -0.27 0.35 includeyourbillingaccountid +invoice-platform 0:a11a3e122422 -0.28 0.35 onyourpaymentremittance. invoice-platform 0:d6577e95efba -0.21 0.07 subtotal invoice-platform 0:6fb943a5640a -0.21 0.02 186.44 invoice-platform 0:26a72d1933a2 -0.20 0.07 tax(5%) @@ -3249,14 +3250,14 @@ invoice-subscription 0:0a36c1665b7e 0.28 0.12 halsteadsoftwareltd. invoice-subscription 0:6bc2056359b7 0.20 0.12 18chandlerrow invoice-subscription 0:776a7e9eb92a 0.22 0.12 leedsls14qt invoice-subscription 0:2474519f77a9 0.24 0.12 unitedkingdom -invoice-subscription 0:2474519f77a9#1 -0.70 0.12 unitedkingdom -invoice-subscription 0:2474519f77a9#2 -0.70 0.07 unitedkingdom +invoice-subscription 0:2474519f77a9#1 0.45 0.12 unitedkingdom +invoice-subscription 0:2474519f77a9#2 0.45 0.07 unitedkingdom invoice-subscription 0:bfdec553b85a 0.24 0.12 billing@halstead.example invoice-subscription 0:78acb3cb907b 0.27 0.12 www.halstead.example invoice-subscription 0:f1c030eb4329 0.29 0.12 vatnogb418227603 invoice-subscription 0:77ead61b5875 0.29 0.09 invoiceno invoice-subscription 0:0b0c0ee24de8 0.26 0.74 hs-inv-2026-0417 -invoice-subscription 0:0b0c0ee24de8#1 -0.07 0.88 hs-inv-2026-0417 +invoice-subscription 0:0b0c0ee24de8#1 0.68 0.88 hs-inv-2026-0417 invoice-subscription 0:8feaf8016bab 0.34 0.09 issuedate invoice-subscription 0:4d49cb78b810 0.32 0.62 27august2026 invoice-subscription 0:ac10f8c16320 0.39 0.09 duedate @@ -3266,77 +3267,77 @@ invoice-subscription 0:56a2e019b8aa 0.42 0.43 14days invoice-subscription 0:466e5b9cd57f 0.50 0.09 currency invoice-subscription 0:54f8e1b3fe44 0.47 0.31 gbp invoice-subscription 0:aeba3a7b3598 0.51 0.12 billto -invoice-subscription 0:7bfc2b791f41 -0.76 0.12 northlineconsultingltd -invoice-subscription 0:7bfc2b791f41#1 -0.76 0.07 northlineconsultingltd -invoice-subscription 0:bcb7024f74fe -0.75 0.12 attn:sarahmitchell -invoice-subscription 0:13dd937d2fe6 -0.73 0.12 21jubileeway -invoice-subscription 0:f9bab6a0b45b -0.72 0.12 londonse13ss +invoice-subscription 0:7bfc2b791f41 0.39 0.12 northlineconsultingltd +invoice-subscription 0:7bfc2b791f41#1 0.39 0.07 northlineconsultingltd +invoice-subscription 0:bcb7024f74fe 0.40 0.12 attn:sarahmitchell +invoice-subscription 0:13dd937d2fe6 0.42 0.12 21jubileeway +invoice-subscription 0:f9bab6a0b45b 0.43 0.12 londonse13ss invoice-subscription 0:725a8f5062e7 0.51 0.07 shipto -invoice-subscription 0:254289ce0191 -0.75 0.07 thefoundry,2ndfloor -invoice-subscription 0:84db1f48facb -0.73 0.07 17-19greatsuffolkstreet -invoice-subscription 0:e7a5f0717d99 -0.72 0.07 londonse10ns -invoice-subscription 0:c9046f7a37ad -0.61 0.12 description -invoice-subscription 0:32e8369a9c4f -0.61 0.13 qty -invoice-subscription 0:d1062d072acd -0.61 0.06 unitprice -invoice-subscription 0:7c512b48ba8a -0.61 0.12 vat -invoice-subscription 0:cf38d95c9c6b -0.61 0.05 amount -invoice-subscription 0:86705447c73d -0.32 0.12 halsteadworkspacepremium(10seats -invoice-subscription 0:0c8dc980db3f -0.32 0.18 £18.00 -invoice-subscription 0:dc934fe30a94 -0.32 0.09 20% -invoice-subscription 0:dc934fe30a94#1 -0.30 0.09 20% -invoice-subscription 0:dc934fe30a94#2 -0.28 0.09 20% -invoice-subscription 0:dc934fe30a94#3 -0.26 0.09 20% -invoice-subscription 0:dc934fe30a94#4 -0.24 0.09 20% -invoice-subscription 0:629184210581 -0.32 0.19 £180.00 -invoice-subscription 0:59df1d2b0f69 -0.30 0.12 hostedplatformservices -invoice-subscription 0:44c1ce3394d2 -0.30 0.16 £420.00 -invoice-subscription 0:44c1ce3394d2#1 -0.30 0.16 £420.00 -invoice-subscription 0:217bada1d20f -0.28 0.12 analyticsprolicences(5seats) -invoice-subscription 0:599cd58953ce -0.28 0.20 £8.40 -invoice-subscription 0:756b8c62fe05 -0.28 0.19 £42.00 -invoice-subscription 0:b055bcc305ed -0.26 0.12 prioritysupportplan -invoice-subscription 0:1077d7cede59 -0.26 0.18 £275.00 -invoice-subscription 0:1077d7cede59#1 -0.26 0.18 £275.00 -invoice-subscription 0:361537ef6a11 -0.24 0.12 voiceadd-on(5seats) -invoice-subscription 0:8bf9ac7b27bd -0.24 0.19 £6.00 -invoice-subscription 0:893d7480f763 -0.24 0.19 £30.00 -invoice-subscription 0:ab5aa97074c4 -0.05 0.12 notes -invoice-subscription 0:4440ed73b83f 0.73 0.12 thisinvoicecoverssoftwaresubscri -invoice-subscription 0:fffc319556fa 0.74 0.12 hostedservicesforthecurrentbilli -invoice-subscription 0:d6577e95efba -0.21 0.11 subtotal -invoice-subscription 0:adde9b2bd3ad -0.21 0.47 £947.00 -invoice-subscription 0:a52611c9261b -0.23 0.11 vat(20%) -invoice-subscription 0:14edcfc20351 -0.23 0.44 £189.40 -invoice-subscription 0:57a66d21eb1b -0.18 0.11 totaldue -invoice-subscription 0:cf1b68cc49ef -0.11 0.94 £1,136.40 -invoice-subscription 0:3c7ade679fdf 1.24 0.12 paymentdetails -invoice-subscription 0:56ed021beb35 -0.03 0.54 beneficiary -invoice-subscription 0:0b85f3c8ed04 -0.07 0.33 halsteadsoftwareltd -invoice-subscription 0:4381dc2ab142 -0.03 0.77 bank -invoice-subscription 0:6d50b2dd724f -0.07 0.84 northgatebank -invoice-subscription 0:10aeacde20ff -0.03 0.83 sortcode -invoice-subscription 0:b19b1415ef9b -0.07 0.99 40-05-30 -invoice-subscription 0:f92a9c925024 -0.03 0.94 accountnumber -invoice-subscription 0:ef797c8118f0 -0.07 0.97 12345678 -invoice-subscription 0:52367a6622b1 -0.03 0.86 reference -invoice-subscription 0:04f7247e8e99 -0.03 0.12 pleaseincludetheinvoicenumberast -invoice-subscription 0:7c6ab37d83ef 0.01 0.09 thankyouforyourbusiness. -invoice-subscription 0:354ffeb2bbc3 -0.03 0.09 paymentisdueby10september2026.if -invoice-subscription 0:7f7d98088133 -0.02 0.09 foranyqueries,pleasecontactbilli +invoice-subscription 0:254289ce0191 0.40 0.07 thefoundry,2ndfloor +invoice-subscription 0:84db1f48facb 0.42 0.07 17-19greatsuffolkstreet +invoice-subscription 0:e7a5f0717d99 0.43 0.07 londonse10ns +invoice-subscription 0:c9046f7a37ad 0.54 0.12 description +invoice-subscription 0:32e8369a9c4f 0.54 0.13 qty +invoice-subscription 0:d1062d072acd 0.54 0.06 unitprice +invoice-subscription 0:7c512b48ba8a 0.54 0.12 vat +invoice-subscription 0:cf38d95c9c6b 0.54 0.05 amount +invoice-subscription 0:86705447c73d 0.83 0.12 halsteadworkspacepremium(10seats +invoice-subscription 0:0c8dc980db3f 0.83 0.18 £18.00 +invoice-subscription 0:dc934fe30a94 0.83 0.09 20% +invoice-subscription 0:dc934fe30a94#1 0.85 0.09 20% +invoice-subscription 0:dc934fe30a94#2 0.87 0.09 20% +invoice-subscription 0:dc934fe30a94#3 0.89 0.09 20% +invoice-subscription 0:dc934fe30a94#4 0.91 0.09 20% +invoice-subscription 0:629184210581 0.83 0.19 £180.00 +invoice-subscription 0:59df1d2b0f69 0.85 0.12 hostedplatformservices +invoice-subscription 0:44c1ce3394d2 0.85 0.16 £420.00 +invoice-subscription 0:44c1ce3394d2#1 0.85 0.16 £420.00 +invoice-subscription 0:217bada1d20f 0.87 0.12 analyticsprolicences(5seats) +invoice-subscription 0:599cd58953ce 0.87 0.20 £8.40 +invoice-subscription 0:756b8c62fe05 0.87 0.19 £42.00 +invoice-subscription 0:b055bcc305ed 0.89 0.12 prioritysupportplan +invoice-subscription 0:1077d7cede59 0.89 0.18 £275.00 +invoice-subscription 0:1077d7cede59#1 0.89 0.18 £275.00 +invoice-subscription 0:361537ef6a11 0.91 0.12 voiceadd-on(5seats) +invoice-subscription 0:8bf9ac7b27bd 0.91 0.19 £6.00 +invoice-subscription 0:893d7480f763 0.91 0.19 £30.00 +invoice-subscription 0:ab5aa97074c4 0.80 0.12 notes +invoice-subscription 0:4440ed73b83f 0.38 0.12 thisinvoicecoverssoftwaresubscri +invoice-subscription 0:fffc319556fa 0.39 0.12 hostedservicesforthecurrentbilli +invoice-subscription 0:d6577e95efba 0.64 0.11 subtotal +invoice-subscription 0:adde9b2bd3ad 0.64 0.47 £947.00 +invoice-subscription 0:a52611c9261b 0.62 0.11 vat(20%) +invoice-subscription 0:14edcfc20351 0.62 0.44 £189.40 +invoice-subscription 0:57a66d21eb1b 0.67 0.11 totaldue +invoice-subscription 0:cf1b68cc49ef 0.74 0.94 £1,136.40 +invoice-subscription 0:3c7ade679fdf 0.79 0.12 paymentdetails +invoice-subscription 0:56ed021beb35 0.72 0.54 beneficiary +invoice-subscription 0:0b85f3c8ed04 0.68 0.33 halsteadsoftwareltd +invoice-subscription 0:4381dc2ab142 0.72 0.77 bank +invoice-subscription 0:6d50b2dd724f 0.68 0.84 northgatebank +invoice-subscription 0:10aeacde20ff 0.72 0.83 sortcode +invoice-subscription 0:b19b1415ef9b 0.68 0.99 40-05-30 +invoice-subscription 0:f92a9c925024 0.72 0.94 accountnumber +invoice-subscription 0:ef797c8118f0 0.68 0.97 12345678 +invoice-subscription 0:52367a6622b1 0.72 0.86 reference +invoice-subscription 0:04f7247e8e99 0.72 0.12 pleaseincludetheinvoicenumberast +invoice-subscription 0:7c6ab37d83ef 0.76 0.09 thankyouforyourbusiness. +invoice-subscription 0:354ffeb2bbc3 0.72 0.09 paymentisdueby10september2026.if +invoice-subscription 0:7f7d98088133 0.73 0.09 foranyqueries,pleasecontactbilli invoice-subscription 0:7b14b8d2c5c4 0.00 0.19 page1of1 invoice-workspace 0:07f15cde5b18 0.15 0.11 kestrel -invoice-workspace 0:07f15cde5b18#1 0.96 0.11 kestrel +invoice-workspace 0:07f15cde5b18#1 -0.04 0.11 kestrel invoice-workspace 0:52d6e3de4fa0 -0.16 0.65 invoice invoice-workspace 0:091019880d88 -0.37 0.13 kestrelcollaboration,inc. -invoice-workspace 0:091019880d88#1 0.37 0.06 kestrelcollaboration,inc. -invoice-workspace 0:091019880d88#2 0.56 0.06 kestrelcollaboration,inc. +invoice-workspace 0:091019880d88#1 -0.28 0.06 kestrelcollaboration,inc. +invoice-workspace 0:091019880d88#2 -0.44 0.06 kestrelcollaboration,inc. invoice-workspace 0:9167e0470dae -0.31 0.13 500howardstreet,6thfloor invoice-workspace 0:efa5e1529794 -0.28 0.13 sanfrancisco,ca94105 invoice-workspace 0:fd7321c405f8 -0.24 0.13 unitedstates invoice-workspace 0:d3c6f273c22d -0.24 0.13 vatid:us77-0560185 invoice-workspace 0:6282391a4cc1 -0.31 0.04 invoicenumber: invoice-workspace 0:b13757c9a6fc -0.30 -0.03 inv-2024-0003521 -invoice-workspace 0:b13757c9a6fc#1 0.18 0.06 inv-2024-0003521 +invoice-workspace 0:b13757c9a6fc#1 -0.47 0.06 inv-2024-0003521 invoice-workspace 0:8d05f5d55191 -0.29 0.04 invoicedate: invoice-workspace 0:8da43dd45024 -0.27 -0.03 27may2024 invoice-workspace 0:d39366fa1423 -0.26 0.04 billingperiod: @@ -3347,7 +3348,7 @@ invoice-workspace 0:18e2cca1098e -0.21 0.04 paymentterms: invoice-workspace 0:98ec3d1fd5b9 -0.20 -0.03 net30 invoice-workspace 0:0e0fb0fc0939 -0.19 0.04 duedate: invoice-workspace 0:f1e2a60122bd -0.18 -0.03 26june2024 -invoice-workspace 0:f1e2a60122bd#1 -0.68 0.10 26june2024 +invoice-workspace 0:f1e2a60122bd#1 -0.33 0.10 26june2024 invoice-workspace 0:aeba3a7b3598 -0.18 0.10 billto invoice-workspace 0:45fe04dbae24 -0.22 0.10 brightfutureltd. invoice-workspace 0:45fe04dbae24#1 -0.22 0.02 brightfutureltd. @@ -3359,60 +3360,60 @@ invoice-workspace 0:c7a9cfdd1c55 -0.13 0.10 vatid:gb987654321 invoice-workspace 0:725a8f5062e7 -0.18 0.02 shipto invoice-workspace 0:6d835e737af6 -0.17 0.02 unit4,riversidepark invoice-workspace 0:555d5194cd4d -0.16 0.02 leedsls14ap -invoice-workspace 0:c9046f7a37ad 0.01 -0.25 description -invoice-workspace 0:169240d91658 0.01 -0.45 plan/service -invoice-workspace 0:32e8369a9c4f 0.01 -0.49 qty -invoice-workspace 0:e2a9c81da5f6 0.01 -0.48 unitprice(usd) -invoice-workspace 0:5dfb966b2bcf 0.01 -0.29 amount(usd) -invoice-workspace 0:2bcc555090a1 -0.09 -0.30 kestrelbusiness+ -invoice-workspace 0:68fad867a983 -0.04 -0.30 workspacesubscription -invoice-workspace 0:e0b844887562 -0.03 -0.17 business+annual -invoice-workspace 0:84906b0f4b73 -0.03 -0.24 50users -invoice-workspace 0:5ee31a6284bc -0.03 -0.21 8.75 -invoice-workspace 0:843d501d422c -0.03 -0.23 437.50 -invoice-workspace 0:3007667b4e18 -0.11 -0.30 enterprisekeymanagement -invoice-workspace 0:162e9c93c528 -0.06 -0.30 customer-managedencryptionkeys -invoice-workspace 0:a33a54a73112 -0.05 -0.19 add-on -invoice-workspace 0:d66c66a96157 -0.05 -0.23 100.00 -invoice-workspace 0:d66c66a96157#1 -0.05 -0.23 100.00 -invoice-workspace 0:0036ebf2cfb2 -0.13 -0.30 prioritysupport -invoice-workspace 0:51833276172f -0.08 -0.30 namedengineerandresponsetarget -invoice-workspace 0:fe6d3468cf5c -0.07 -0.20 standard -invoice-workspace 0:a99210875f11 -0.07 -0.24 50.00 -invoice-workspace 0:a99210875f11#1 -0.07 -0.20 50.00 -invoice-workspace 0:14209e8ccd53 -0.15 -0.30 workflowautomation -invoice-workspace 0:31be3ff05457 -0.10 -0.30 templatesandscheduledruns -invoice-workspace 0:7f0f70e643bc -0.09 -0.21 included -invoice-workspace 0:561b2814d3c0 -0.09 -0.21 0.00 -invoice-workspace 0:561b2814d3c0#1 -0.09 -0.22 0.00 -invoice-workspace 0:561b2814d3c0#2 -0.04 0.34 0.00 -invoice-workspace 0:3c7ade679fdf 0.32 0.08 paymentdetails -invoice-workspace 0:944d398aea60 0.41 0.12 bankname: -invoice-workspace 0:a18e9fdf120e 0.41 0.06 bayunionbank,n.a. -invoice-workspace 0:0ecb5847ffa7 0.37 0.12 accountname: -invoice-workspace 0:6b4894c28363 0.33 0.12 accountnumber: -invoice-workspace 0:ab92799f9bc7 0.33 0.06 000000123456789 -invoice-workspace 0:c1390f638bd3 0.29 0.12 routing(aba): -invoice-workspace 0:1f873cdde0ca 0.29 0.06 021000021 -invoice-workspace 0:e58256751597 0.26 0.12 swift/bic: -invoice-workspace 0:0fdf54f117f8 0.26 0.06 bayuus33 -invoice-workspace 0:967e0b6ca4b9 0.22 0.12 currency: -invoice-workspace 0:d60fbd8718ec 0.22 0.06 usd -invoice-workspace 0:c608665436db 0.18 0.12 reference: -invoice-workspace 0:3db3fa89ea2c 0.14 0.12 bankaddress: -invoice-workspace 0:b1645851e755 0.14 0.06 1marketplaza,sanfrancisco -invoice-workspace 0:9b600d1211c8 1.08 0.14 pleaseincludetheinvoicenumberiny -invoice-workspace 0:415eb9e42f41 -0.18 0.14 reference. -invoice-workspace 0:d6577e95efba -0.04 0.13 subtotal -invoice-workspace 0:460dd5bae888 -0.04 0.40 587.50 -invoice-workspace 0:2ee4d3de4ddf -0.04 0.13 tax(0%) -invoice-workspace 0:57a66d21eb1b -0.11 0.13 totaldue -invoice-workspace 0:ad00e93ce79a -0.19 0.62 usd587.50 -invoice-workspace 0:b0553f008513 -0.57 0.10 paymentdueby -invoice-workspace 0:08775a92bfca 0.59 0.12 thankyouforusingkestrel. -invoice-workspace 0:18e82fbd48a3 0.66 0.12 questionsaboutthisinvoice?reachu -invoice-workspace 0:3c72ba0e1eb8 0.53 0.06 500howardstreet,6thfloor,sanfran -invoice-workspace 0:9e2917e23527 0.52 -0.12 kestrel.example +invoice-workspace 0:c9046f7a37ad -0.09 -0.25 description +invoice-workspace 0:169240d91658 -0.09 -0.45 plan/service +invoice-workspace 0:32e8369a9c4f -0.09 -0.49 qty +invoice-workspace 0:e2a9c81da5f6 -0.09 -0.48 unitprice(usd) +invoice-workspace 0:5dfb966b2bcf -0.09 -0.29 amount(usd) +invoice-workspace 0:2bcc555090a1 -0.19 -0.30 kestrelbusiness+ +invoice-workspace 0:68fad867a983 -0.14 -0.30 workspacesubscription +invoice-workspace 0:e0b844887562 -0.13 -0.17 business+annual +invoice-workspace 0:84906b0f4b73 -0.13 -0.24 50users +invoice-workspace 0:5ee31a6284bc -0.13 -0.21 8.75 +invoice-workspace 0:843d501d422c -0.13 -0.23 437.50 +invoice-workspace 0:3007667b4e18 -0.21 -0.30 enterprisekeymanagement +invoice-workspace 0:162e9c93c528 -0.16 -0.30 customer-managedencryptionkeys +invoice-workspace 0:a33a54a73112 -0.15 -0.19 add-on +invoice-workspace 0:d66c66a96157 -0.15 -0.23 100.00 +invoice-workspace 0:d66c66a96157#1 -0.15 -0.23 100.00 +invoice-workspace 0:0036ebf2cfb2 -0.23 -0.30 prioritysupport +invoice-workspace 0:51833276172f -0.18 -0.30 namedengineerandresponsetarget +invoice-workspace 0:fe6d3468cf5c -0.17 -0.20 standard +invoice-workspace 0:a99210875f11 -0.17 -0.24 50.00 +invoice-workspace 0:a99210875f11#1 -0.17 -0.20 50.00 +invoice-workspace 0:14209e8ccd53 -0.25 -0.30 workflowautomation +invoice-workspace 0:31be3ff05457 -0.20 -0.30 templatesandscheduledruns +invoice-workspace 0:7f0f70e643bc -0.19 -0.21 included +invoice-workspace 0:561b2814d3c0 -0.19 -0.21 0.00 +invoice-workspace 0:561b2814d3c0#1 -0.19 -0.22 0.00 +invoice-workspace 0:561b2814d3c0#2 -0.14 0.34 0.00 +invoice-workspace 0:3c7ade679fdf -0.23 0.08 paymentdetails +invoice-workspace 0:944d398aea60 -0.24 0.12 bankname: +invoice-workspace 0:a18e9fdf120e -0.24 0.06 bayunionbank,n.a. +invoice-workspace 0:0ecb5847ffa7 -0.28 0.12 accountname: +invoice-workspace 0:6b4894c28363 -0.32 0.12 accountnumber: +invoice-workspace 0:ab92799f9bc7 -0.32 0.06 000000123456789 +invoice-workspace 0:c1390f638bd3 -0.36 0.12 routing(aba): +invoice-workspace 0:1f873cdde0ca -0.36 0.06 021000021 +invoice-workspace 0:e58256751597 -0.39 0.12 swift/bic: +invoice-workspace 0:0fdf54f117f8 -0.39 0.06 bayuus33 +invoice-workspace 0:967e0b6ca4b9 -0.43 0.12 currency: +invoice-workspace 0:d60fbd8718ec -0.43 0.06 usd +invoice-workspace 0:c608665436db -0.47 0.12 reference: +invoice-workspace 0:3db3fa89ea2c -0.51 0.12 bankaddress: +invoice-workspace 0:b1645851e755 -0.51 0.06 1marketplaza,sanfrancisco +invoice-workspace 0:9b600d1211c8 0.43 0.14 pleaseincludetheinvoicenumberiny +invoice-workspace 0:415eb9e42f41 -0.83 0.14 reference. +invoice-workspace 0:d6577e95efba -0.14 0.13 subtotal +invoice-workspace 0:460dd5bae888 -0.14 0.40 587.50 +invoice-workspace 0:2ee4d3de4ddf -0.14 0.13 tax(0%) +invoice-workspace 0:57a66d21eb1b -0.21 0.13 totaldue +invoice-workspace 0:ad00e93ce79a -0.29 0.62 usd587.50 +invoice-workspace 0:b0553f008513 -0.22 0.10 paymentdueby +invoice-workspace 0:08775a92bfca -0.41 0.12 thankyouforusingkestrel. +invoice-workspace 0:18e82fbd48a3 -0.34 0.12 questionsaboutthisinvoice?reachu +invoice-workspace 0:3c72ba0e1eb8 -0.47 0.06 500howardstreet,6thfloor,sanfran +invoice-workspace 0:9e2917e23527 -0.48 -0.12 kestrel.example invoice-workspace 0:7b14b8d2c5c4 -0.05 -0.03 page1of1 letter-blue_banner 0:8f1010120ed6 0.42 1.95 jordanrivera letter-blue_banner 0:8f1010120ed6#1 -0.02 0.10 jordanrivera @@ -3425,15 +3426,15 @@ letter-blue_banner 0:eae27893a255 -0.42 0.10 therestoftheteam. letter-blue_banner 0:a71e98216baa -0.08 0.10 iwouldwelcometheopportunitytobri letter-blue_banner 0:80a6a628ad52 -0.05 0.10 sincerely, letter-boxed_sections 0:8f1010120ed6 0.46 2.20 jordanrivera -letter-boxed_sections 0:8f1010120ed6#1 -0.37 0.10 jordanrivera -letter-boxed_sections 0:8d7a2cca3060 -0.12 0.22 +442055551000|jordan.rivera@exam -letter-boxed_sections 0:bef81b541365 -0.41 0.10 dearhiringteamatnorthwindsystems -letter-boxed_sections 0:ab54410ead82 -0.71 0.10 iamexcitedtosharemyinterestinthe -letter-boxed_sections 0:9185168d2cf8 -0.70 0.10 document-generationsystemsthatba -letter-boxed_sections 0:5fb2802723b6 -0.70 0.10 ienjoytranslatingfuzzyworkflowre -letter-boxed_sections 0:dab2d688b7ab -0.69 0.10 adoptioneasierfortherestofthetea -letter-boxed_sections 0:a71e98216baa -0.39 0.10 iwouldwelcometheopportunitytobri -letter-boxed_sections 0:80a6a628ad52 -0.38 0.10 sincerely, +letter-boxed_sections 0:8f1010120ed6#1 0.33 0.10 jordanrivera +letter-boxed_sections 0:8d7a2cca3060 0.23 0.22 +442055551000|jordan.rivera@exam +letter-boxed_sections 0:bef81b541365 0.29 0.10 dearhiringteamatnorthwindsystems +letter-boxed_sections 0:ab54410ead82 -0.01 0.10 iamexcitedtosharemyinterestinthe +letter-boxed_sections 0:9185168d2cf8 0.00 0.10 document-generationsystemsthatba +letter-boxed_sections 0:5fb2802723b6 0.00 0.10 ienjoytranslatingfuzzyworkflowre +letter-boxed_sections 0:dab2d688b7ab 0.01 0.10 adoptioneasierfortherestofthetea +letter-boxed_sections 0:a71e98216baa 0.31 0.10 iwouldwelcometheopportunitytobri +letter-boxed_sections 0:80a6a628ad52 0.32 0.10 sincerely, letter-centered_headline 0:8f1010120ed6 -0.50 2.44 jordanrivera letter-centered_headline 0:8f1010120ed6#1 -0.06 0.10 jordanrivera letter-centered_headline 0:2d58f0cadc2d -0.18 1.40 platformengineer @@ -3476,20 +3477,20 @@ letter-editorial_blue 0:dda41d31bb3c -0.15 0.10 thatmakeadoptioneasierfortherest letter-editorial_blue 0:a71e98216baa 0.16 0.10 iwouldwelcometheopportunitytobri letter-editorial_blue 0:80a6a628ad52 0.16 0.10 sincerely, letter-engineering_resume 0:8f1010120ed6 0.15 0.10 jordanrivera -letter-engineering_resume 0:8f1010120ed6#1 -1.41 0.10 jordanrivera +letter-engineering_resume 0:8f1010120ed6#1 -0.16 0.10 jordanrivera letter-engineering_resume 0:2d58f0cadc2d -0.25 0.10 platformengineer letter-engineering_resume 0:fbeea547d99e -0.21 0.36 london,uk letter-engineering_resume 0:89674e6f130e -0.20 0.34 +442055551000 letter-engineering_resume 0:e0f850305ded -0.19 0.25 jordan.rivera@example.com letter-engineering_resume 0:84308bea4540 -0.18 0.95 linkedin letter-engineering_resume 0:c0b0109d9439 -0.17 0.85 github -letter-engineering_resume 0:bef81b541365 -1.40 0.10 dearhiringteamatnorthwindsystems -letter-engineering_resume 0:c5331fbe74e1 -1.67 0.10 iamexcitedtosharemyinterestinthe -letter-engineering_resume 0:f27264b519fd -1.65 0.10 balancepublicapidesign,renderqua -letter-engineering_resume 0:b98ace48a28b -1.66 0.10 ienjoytranslatingfuzzyworkflowre -letter-engineering_resume 0:30edab94d52e -1.64 0.10 oftheteam. -letter-engineering_resume 0:a71e98216baa -1.40 0.10 iwouldwelcometheopportunitytobri -letter-engineering_resume 0:80a6a628ad52 -1.41 0.10 sincerely, +letter-engineering_resume 0:bef81b541365 -0.15 0.10 dearhiringteamatnorthwindsystems +letter-engineering_resume 0:c5331fbe74e1 -0.42 0.10 iamexcitedtosharemyinterestinthe +letter-engineering_resume 0:f27264b519fd -0.40 0.10 balancepublicapidesign,renderqua +letter-engineering_resume 0:b98ace48a28b -0.41 0.10 ienjoytranslatingfuzzyworkflowre +letter-engineering_resume 0:30edab94d52e -0.39 0.10 oftheteam. +letter-engineering_resume 0:a71e98216baa -0.15 0.10 iwouldwelcometheopportunitytobri +letter-engineering_resume 0:80a6a628ad52 -0.16 0.10 sincerely, letter-executive 0:8f1010120ed6 -0.50 0.10 jordanrivera letter-executive 0:8f1010120ed6#1 -0.10 0.10 jordanrivera letter-executive 0:89ff05847e96 -0.28 0.10 london,uk|+442055551000 @@ -3513,17 +3514,17 @@ letter-mint-editorial-letter 0:dd474e249222 0.29 0.10 makeadoptioneasierforthere letter-mint-editorial-letter 0:a71e98216baa -0.16 0.10 iwouldwelcometheopportunitytobri letter-mint-editorial-letter 0:80a6a628ad52 -0.16 0.10 sincerely, letter-modern_professional 0:8f1010120ed6 0.00 0.21 jordanrivera -letter-modern_professional 0:8f1010120ed6#1 -0.13 0.10 jordanrivera +letter-modern_professional 0:8f1010120ed6#1 0.27 0.10 jordanrivera letter-modern_professional 0:89ff05847e96 0.14 0.26 london,uk|+442055551000 letter-modern_professional 0:8817bf9310b6 0.11 0.30 jordan.rivera@example.com|linked -letter-modern_professional 0:bef81b541365 -0.13 0.10 dearhiringteamatnorthwindsystems -letter-modern_professional 0:c65db8c80e17 -0.43 0.10 iamexcitedtosharemyinterestinthe -letter-modern_professional 0:c8d01ef84078 -0.43 0.10 reusabledocument-generationsyste -letter-modern_professional 0:2e5ddee14dbc -0.43 0.10 ienjoytranslatingfuzzyworkflowre -letter-modern_professional 0:906501a5e847 -0.43 0.10 examplesthatmakeadoptioneasierfo -letter-modern_professional 0:7c5a9817c868 -0.43 0.10 iwouldwelcometheopportunitytobri -letter-modern_professional 0:4012eb4b05db -0.43 0.10 group. -letter-modern_professional 0:80a6a628ad52 -0.13 0.10 sincerely, +letter-modern_professional 0:bef81b541365 0.27 0.10 dearhiringteamatnorthwindsystems +letter-modern_professional 0:c65db8c80e17 -0.03 0.10 iamexcitedtosharemyinterestinthe +letter-modern_professional 0:c8d01ef84078 -0.03 0.10 reusabledocument-generationsyste +letter-modern_professional 0:2e5ddee14dbc -0.03 0.10 ienjoytranslatingfuzzyworkflowre +letter-modern_professional 0:906501a5e847 -0.03 0.10 examplesthatmakeadoptioneasierfo +letter-modern_professional 0:7c5a9817c868 -0.03 0.10 iwouldwelcometheopportunitytobri +letter-modern_professional 0:4012eb4b05db -0.03 0.10 group. +letter-modern_professional 0:80a6a628ad52 0.27 0.10 sincerely, letter-monogram_sidebar 0:136c67657614 -0.38 2.82 jordan letter-monogram_sidebar 0:8ba35ebe3d5c -0.37 2.85 rivera letter-monogram_sidebar 0:2d58f0cadc2d -0.19 0.13 platformengineer @@ -3551,11 +3552,11 @@ letter-nordic_clean 0:26e89af4523d -0.38 0.10 ienjoytranslatingfuzzyworkflowre letter-nordic_clean 0:27c5581ffbbc -0.39 0.10 restoftheteam. letter-nordic_clean 0:a71e98216baa -0.14 0.10 iwouldwelcometheopportunitytobri letter-nordic_clean 0:80a6a628ad52 -0.14 0.10 sincerely, -letter-panel 0:8f1010120ed6 -0.40 0.32 jordanrivera +letter-panel 0:8f1010120ed6 -0.65 0.32 jordanrivera letter-panel 0:8f1010120ed6#1 0.16 0.10 jordanrivera -letter-panel 0:2d58f0cadc2d 0.12 0.07 platformengineer -letter-panel 0:89ff05847e96 0.19 0.29 london,uk|+442055551000 -letter-panel 0:8817bf9310b6 0.21 0.35 jordan.rivera@example.com|linked +letter-panel 0:2d58f0cadc2d -0.13 0.07 platformengineer +letter-panel 0:89ff05847e96 -0.06 0.29 london,uk|+442055551000 +letter-panel 0:8817bf9310b6 -0.04 0.35 jordan.rivera@example.com|linked letter-panel 0:bef81b541365 0.01 0.10 dearhiringteamatnorthwindsystems letter-panel 0:ab54410ead82 -0.17 0.10 iamexcitedtosharemyinterestinthe letter-panel 0:9185168d2cf8 -0.15 0.10 document-generationsystemsthatba @@ -3609,43 +3610,43 @@ proposal-editorial 0:53fcd88ebb00 0.57 0.10 cohesivebrandsystemandamodern,co proposal-editorial 0:95bad9757a67 0.57 0.10 outcomewillbeaclear,confidentpre proposal-editorial 0:8863e2b998da 0.57 0.10 improvesengagement,andsupportsyo proposal-editorial 0:f16c2c2f1999 -0.92 0.10 projectgoals -proposal-editorial 0:c008ab0ba85f -0.19 0.10 projectduration -proposal-editorial 0:5a6b4bf425f2 -0.41 0.10 6weeks -proposal-editorial 0:7aa73e5c14d3 -0.12 0.10 startwindow -proposal-editorial 0:6fcb2d3f02ba -0.33 0.10 september2026 -proposal-editorial 0:185e8dc84248 -0.05 0.10 primarycontact -proposal-editorial 0:59d00e0c1b99 -0.26 0.10 projectlead -proposal-editorial 0:4190fd3a8d72 -0.01 0.10 proposalvalidity -proposal-editorial 0:56a2e019b8aa -0.22 0.10 14days -proposal-editorial 0:265e93f6b9da -0.05 0.10 (until8september2026) -proposal-editorial 0:e2ea93b97611 1.05 0.05 strengthenbrand -proposal-editorial 0:7d95098b921b 0.05 0.05 credibilityandvisual -proposal-editorial 0:218e304f8b84 -0.95 0.05 consistency. -proposal-editorial 0:35597cc9803f 1.05 0.06 improvewebsite -proposal-editorial 0:83f63137756b 0.05 0.06 usabilityanddrive -proposal-editorial 0:cce9fba37d4e -0.95 0.06 meaningfulaction. -proposal-editorial 0:59aaadaf0c54 1.05 0.06 communicateyour -proposal-editorial 0:30193022f687 0.05 0.06 valueclearlyacrossall -proposal-editorial 0:04b5995c746f -0.95 0.06 touchpoints. -proposal-editorial 0:b45d848fe1b6 1.05 0.07 buildascalabledigital -proposal-editorial 0:e8228bfeba0e 0.05 0.07 foundationforfuture -proposal-editorial 0:1fa35c7a1402 -0.95 0.07 growth. -proposal-editorial 0:bc981abcdf59 -1.43 0.10 scopeofwork -proposal-editorial 0:28450edd9a4f -0.35 0.05 discovery&research -proposal-editorial 0:ce9012b74aa2 -0.10 0.08 stakeholderinterviews,brandaudit -proposal-editorial 0:730c3e278933 -0.38 0.08 audienceinsightstoinformstrategy -proposal-editorial 0:12bff3036b66 -0.26 0.05 visualidentityrefinement -proposal-editorial 0:937ad523a90c -0.01 0.08 refinelogosystem,colorpalette,ty -proposal-editorial 0:9b232e66f46c -0.29 0.08 guidelinesforacohesive,modernide -proposal-editorial 0:fc5134bf5fd1 -0.17 0.05 websiteux/uidesign -proposal-editorial 0:5d58b01c7096 0.08 0.08 designaresponsive,accessibility- -proposal-editorial 0:5d6068f6a879 -0.20 0.08 navigationandclearconversionpath -proposal-editorial 0:32001e20b2ed -0.08 0.05 contentstructure&messaging -proposal-editorial 0:b3c948ec3e36 0.17 0.08 definesitearchitecture,keymessag -proposal-editorial 0:231428fde7aa -0.11 0.08 communicatevalueandbuildtrust. -proposal-editorial 0:8c7703bb6fb7 0.01 0.05 launchsupport -proposal-editorial 0:34f9fe468474 0.26 0.08 developerhandoff,qasupport,train -proposal-editorial 0:2b4cf15f6f16 -0.02 0.08 toensureasmoothlaunch. +proposal-editorial 0:c008ab0ba85f 0.16 0.10 projectduration +proposal-editorial 0:5a6b4bf425f2 -0.05 0.10 6weeks +proposal-editorial 0:7aa73e5c14d3 0.23 0.10 startwindow +proposal-editorial 0:6fcb2d3f02ba 0.02 0.10 september2026 +proposal-editorial 0:185e8dc84248 0.30 0.10 primarycontact +proposal-editorial 0:59d00e0c1b99 0.09 0.10 projectlead +proposal-editorial 0:4190fd3a8d72 0.35 0.10 proposalvalidity +proposal-editorial 0:56a2e019b8aa 0.13 0.10 14days +proposal-editorial 0:265e93f6b9da 0.30 0.10 (until8september2026) +proposal-editorial 0:e2ea93b97611 1.75 0.05 strengthenbrand +proposal-editorial 0:7d95098b921b 0.75 0.05 credibilityandvisual +proposal-editorial 0:218e304f8b84 -0.25 0.05 consistency. +proposal-editorial 0:35597cc9803f 1.75 0.06 improvewebsite +proposal-editorial 0:83f63137756b 0.75 0.06 usabilityanddrive +proposal-editorial 0:cce9fba37d4e -0.25 0.06 meaningfulaction. +proposal-editorial 0:59aaadaf0c54 1.75 0.06 communicateyour +proposal-editorial 0:30193022f687 0.75 0.06 valueclearlyacrossall +proposal-editorial 0:04b5995c746f -0.25 0.06 touchpoints. +proposal-editorial 0:b45d848fe1b6 1.75 0.07 buildascalabledigital +proposal-editorial 0:e8228bfeba0e 0.75 0.07 foundationforfuture +proposal-editorial 0:1fa35c7a1402 -0.25 0.07 growth. +proposal-editorial 0:bc981abcdf59 -0.73 0.10 scopeofwork +proposal-editorial 0:28450edd9a4f 0.35 0.05 discovery&research +proposal-editorial 0:ce9012b74aa2 0.60 0.08 stakeholderinterviews,brandaudit +proposal-editorial 0:730c3e278933 0.32 0.08 audienceinsightstoinformstrategy +proposal-editorial 0:12bff3036b66 0.44 0.05 visualidentityrefinement +proposal-editorial 0:937ad523a90c 0.69 0.08 refinelogosystem,colorpalette,ty +proposal-editorial 0:9b232e66f46c 0.41 0.08 guidelinesforacohesive,modernide +proposal-editorial 0:fc5134bf5fd1 0.53 0.05 websiteux/uidesign +proposal-editorial 0:5d58b01c7096 0.78 0.08 designaresponsive,accessibility- +proposal-editorial 0:5d6068f6a879 0.50 0.08 navigationandclearconversionpath +proposal-editorial 0:32001e20b2ed 0.62 0.05 contentstructure&messaging +proposal-editorial 0:b3c948ec3e36 0.87 0.08 definesitearchitecture,keymessag +proposal-editorial 0:231428fde7aa 0.59 0.08 communicatevalueandbuildtrust. +proposal-editorial 0:8c7703bb6fb7 0.71 0.05 launchsupport +proposal-editorial 0:34f9fe468474 0.96 0.08 developerhandoff,qasupport,train +proposal-editorial 0:2b4cf15f6f16 0.68 0.08 toensureasmoothlaunch. proposal-editorial 0:026890c58de9 0.01 0.10 northlinestudio|northlinestudio. proposal-editorial 1:e35c32bb5ed8 -46.41 0.10 deliverables proposal-editorial 1:23eb79a19b39 -45.38 0.57 brandstrategysummary @@ -3714,11 +3715,11 @@ proposal-editorial 1:566f68df6dd8 -44.99 0.14 finalpayment. proposal-editorial 1:06ebb5670fa8 -45.31 0.59 ownershipofallfinaldeliverables proposal-editorial 1:deda6d86d965 -44.96 0.14 transferstoasterahealthco.after proposal-editorial 1:aaa7d3e9affb -45.38 0.14 fullpaymentisreceived. -proposal-editorial 1:c1514c6cdad1 -45.64 0.10 acceptance -proposal-editorial 1:893663b06769 -44.61 0.10 bysigningbelow,youagreetothescop -proposal-editorial 1:df16232de5b9 -44.62 0.10 acceptedby: -proposal-editorial 1:f089d24d7cf3 -44.62 -0.02 signature: -proposal-editorial 1:c74c9cd82f13 -44.62 -0.16 date: +proposal-editorial 1:c1514c6cdad1 -45.29 0.10 acceptance +proposal-editorial 1:893663b06769 -44.26 0.10 bysigningbelow,youagreetothescop +proposal-editorial 1:df16232de5b9 -44.27 0.10 acceptedby: +proposal-editorial 1:f089d24d7cf3 -44.27 -0.02 signature: +proposal-editorial 1:c74c9cd82f13 -44.27 -0.16 date: proposal-editorial 1:026890c58de9 0.01 0.10 northlinestudio|northlinestudio. proposal-indigo 0:07f15cde5b18 0.14 0.08 kestrel proposal-indigo 0:ecd1378bc9dc 0.13 -0.38 proposal @@ -3793,47 +3794,47 @@ proposal-indigo 0:29208032c874 0.72 0.05 kestrel.example/business|busines proposal-modern 0:ecd1378bc9dc 0.00 0.10 proposal proposal-modern 0:f592a683c61d 0.27 0.10 documentplatformconsolidation proposal-modern 0:bbe07492ee1f 0.32 0.10 proposalgc-p-2026-014prepared02a -proposal-modern 0:566835ed7fba -0.07 0.10 executivesummary -proposal-modern 0:7ccf0e6c59fa -0.10 0.10 aphasedengagementtoretireper-tea -proposal-modern 0:75857a458999 -0.42 0.10 from -proposal-modern 0:c26c22b94338 -0.45 0.10 graphcomposestudio -proposal-modern 0:2a08ce5567fb -0.72 0.10 18layoutstreet -proposal-modern 0:fbeea547d99e -0.75 0.10 london,uk -proposal-modern 0:3c8401edb4cc -0.77 0.10 hello@graphcompose.dev -proposal-modern 0:89674e6f130e -0.80 0.10 +442055551000 -proposal-modern 0:213a61c7aeb6 -0.82 0.10 graphcompose.dev -proposal-modern 0:f890faef907f -0.45 0.11 northwindsystems -proposal-modern 0:577a7fcdaa02 -0.72 0.11 attn:procurement -proposal-modern 0:91eefd794f79 -0.75 0.11 410marketavenue -proposal-modern 0:3daace874084 -0.77 0.11 procurement@northwind.example -proposal-modern 0:5f161c914988 -0.41 0.10 scope -proposal-modern 0:9e580657f485 -0.57 0.10 discovery,architecture,andarefer -proposal-modern 0:cec9111de36d -0.41 0.10 approach -proposal-modern 0:3215ea3be6d9 -0.57 0.10 iterativedeliverywithweeklycheck -proposal-modern 0:94d192b3a326 -0.41 0.10 timeline -proposal-modern 0:02195b8e9896 -0.57 -0.20 phase -proposal-modern 0:caa79af4db67 -0.57 -0.25 duration -proposal-modern 0:41ffd8b76afc -0.57 -0.25 details -proposal-modern 0:fa44132b238e -0.50 -0.20 discovery -proposal-modern 0:fa44132b238e#1 -0.50 -0.20 discovery -proposal-modern 0:b183847fe9f8 -0.50 -0.25 2weeks -proposal-modern 0:4b20bfb69ca7 -0.50 -0.25 stakeholderinterviews+audit -proposal-modern 0:44575cf5b285 -0.50 -0.20 build -proposal-modern 0:44575cf5b285#1 -0.50 -0.20 build -proposal-modern 0:5a6b4bf425f2 -0.50 -0.25 6weeks -proposal-modern 0:7a802048127d -0.50 -0.25 engine+templatemigration -proposal-modern 0:f9b21c4bda58 -0.41 0.10 investment -proposal-modern 0:4a33eacd5fa6 -0.57 -0.20 item -proposal-modern 0:c9046f7a37ad -0.57 -0.25 description -proposal-modern 0:cf38d95c9c6b -0.57 0.82 amount -proposal-modern 0:fe9b6b4f133b -0.50 -0.25 workshops+auditgbp6,000 -proposal-modern 0:62e788ae3916 -0.50 -0.25 engine+templatesgbp24,000 -proposal-modern 0:11239872d178 -0.60 -0.20 total -proposal-modern 0:1c3065490625 -0.60 0.82 gbp30,000 -proposal-modern 0:63feb7230a5d -0.43 0.10 acceptanceterms -proposal-modern 0:35046a9f5675 -0.50 0.10 •50%onsignature,50%ondelivery. -proposal-modern 0:f03c1877ea2b -0.50 0.10 •validfor30daysfromthepreparedda -proposal-modern 0:90572e911376 -0.58 0.10 thankyouforconsideringgraphcompo +proposal-modern 0:566835ed7fba 0.23 0.10 executivesummary +proposal-modern 0:7ccf0e6c59fa 0.20 0.10 aphasedengagementtoretireper-tea +proposal-modern 0:75857a458999 0.23 0.10 from +proposal-modern 0:c26c22b94338 0.20 0.10 graphcomposestudio +proposal-modern 0:2a08ce5567fb -0.07 0.10 18layoutstreet +proposal-modern 0:fbeea547d99e -0.10 0.10 london,uk +proposal-modern 0:3c8401edb4cc -0.12 0.10 hello@graphcompose.dev +proposal-modern 0:89674e6f130e -0.15 0.10 +442055551000 +proposal-modern 0:213a61c7aeb6 -0.17 0.10 graphcompose.dev +proposal-modern 0:f890faef907f 0.20 0.11 northwindsystems +proposal-modern 0:577a7fcdaa02 -0.07 0.11 attn:procurement +proposal-modern 0:91eefd794f79 -0.10 0.11 410marketavenue +proposal-modern 0:3daace874084 -0.12 0.11 procurement@northwind.example +proposal-modern 0:5f161c914988 0.24 0.10 scope +proposal-modern 0:9e580657f485 0.08 0.10 discovery,architecture,andarefer +proposal-modern 0:cec9111de36d 0.24 0.10 approach +proposal-modern 0:3215ea3be6d9 0.08 0.10 iterativedeliverywithweeklycheck +proposal-modern 0:94d192b3a326 0.24 0.10 timeline +proposal-modern 0:02195b8e9896 0.08 -0.20 phase +proposal-modern 0:caa79af4db67 0.08 -0.25 duration +proposal-modern 0:41ffd8b76afc 0.08 -0.25 details +proposal-modern 0:fa44132b238e 0.15 -0.20 discovery +proposal-modern 0:fa44132b238e#1 0.15 -0.20 discovery +proposal-modern 0:b183847fe9f8 0.15 -0.25 2weeks +proposal-modern 0:4b20bfb69ca7 0.15 -0.25 stakeholderinterviews+audit +proposal-modern 0:44575cf5b285 0.15 -0.20 build +proposal-modern 0:44575cf5b285#1 0.15 -0.20 build +proposal-modern 0:5a6b4bf425f2 0.15 -0.25 6weeks +proposal-modern 0:7a802048127d 0.15 -0.25 engine+templatemigration +proposal-modern 0:f9b21c4bda58 0.24 0.10 investment +proposal-modern 0:4a33eacd5fa6 0.08 -0.20 item +proposal-modern 0:c9046f7a37ad 0.08 -0.25 description +proposal-modern 0:cf38d95c9c6b 0.08 0.82 amount +proposal-modern 0:fe9b6b4f133b 0.15 -0.25 workshops+auditgbp6,000 +proposal-modern 0:62e788ae3916 0.15 -0.25 engine+templatesgbp24,000 +proposal-modern 0:11239872d178 0.05 -0.20 total +proposal-modern 0:1c3065490625 0.05 0.82 gbp30,000 +proposal-modern 0:63feb7230a5d 0.22 0.10 acceptanceterms +proposal-modern 0:35046a9f5675 0.15 0.10 •50%onsignature,50%ondelivery. +proposal-modern 0:f03c1877ea2b 0.15 0.10 •validfor30daysfromthepreparedda +proposal-modern 0:90572e911376 0.07 0.10 thankyouforconsideringgraphcompo proposal-northline 0:5205c2a261bc -0.44 0.05 northline proposal-northline 0:da0daaba4b15 -0.44 0.05 studio proposal-northline 0:ecd1378bc9dc -0.38 1.98 proposal @@ -3960,11 +3961,11 @@ proposal-northline 1:566f68df6dd8 0.05 0.09 finalpayment. proposal-northline 1:06ebb5670fa8 0.33 0.54 ownershipofallfinaldeliverables proposal-northline 1:5312201597c1 0.70 0.09 transferstoasterahealthco.afterf proposal-northline 1:d31e8d77a816 0.30 0.09 paymentisreceived. -proposal-northline 1:c1514c6cdad1 0.06 0.11 acceptance -proposal-northline 1:893663b06769 0.38 0.10 bysigningbelow,youagreetothescop -proposal-northline 1:df16232de5b9 0.37 0.10 acceptedby: -proposal-northline 1:f089d24d7cf3 0.37 0.06 signature: -proposal-northline 1:c74c9cd82f13 0.37 0.07 date: +proposal-northline 1:c1514c6cdad1 0.41 0.11 acceptance +proposal-northline 1:893663b06769 0.73 0.10 bysigningbelow,youagreetothescop +proposal-northline 1:df16232de5b9 0.72 0.10 acceptedby: +proposal-northline 1:f089d24d7cf3 0.72 0.06 signature: +proposal-northline 1:c74c9cd82f13 0.72 0.07 date: proposal-northline 1:026890c58de9 0.01 0.10 northlinestudio|northlinestudio. receipt-modern 0:2b019b5b46da 0.31 0.10 northwindpay receipt-modern 0:a3c304a23bb1 0.30 0.21 transferconfirmation diff --git a/qa/src/test/resources/docx-fidelity/libreoffice-windows.tsv b/qa/src/test/resources/docx-fidelity/libreoffice-windows.tsv index b06e0b821..7fca37b0d 100644 --- a/qa/src/test/resources/docx-fidelity/libreoffice-windows.tsv +++ b/qa/src/test/resources/docx-fidelity/libreoffice-windows.tsv @@ -1,64 +1,64 @@ # libreoffice build bce0998afefd on windows document engine_pages editor_pages lines matched median p90 over2 cv-blue_banner 2 2 54 52 0.14 0.46 0 -cv-boxed_sections 2 2 58 58 0.35 0.63 0 +cv-boxed_sections 2 2 58 58 0.26 0.37 0 cv-centered_headline 2 2 58 56 0.14 0.32 0 -cv-charcoal_gold 1 1 85 83 0.11 0.34 0 -cv-classic_serif 2 2 57 54 0.06 0.22 0 -cv-compact_mono 1 1 58 58 0.34 0.83 0 +cv-charcoal_gold 1 1 85 83 0.17 0.24 0 +cv-classic_serif 2 2 57 54 0.26 0.31 0 +cv-compact_mono 1 1 58 58 0.24 0.83 0 cv-editorial_blue 2 2 82 82 0.08 0.30 0 -cv-engineering_resume 1 1 57 57 0.60 1.62 0 +cv-engineering_resume 1 1 57 57 0.28 0.41 0 cv-executive 2 2 60 60 0.26 0.50 0 cv-midnight_navy 1 1 86 84 0.28 0.87 0 -cv-minimal_underlined 2 2 59 59 0.72 1.39 0 +cv-minimal_underlined 2 2 59 59 0.35 0.64 0 cv-mint_editorial 2 2 59 59 0.27 0.60 0 -cv-modern_professional 2 2 61 59 0.12 0.41 0 +cv-modern_professional 2 2 61 59 0.28 0.30 0 cv-monogram_sidebar 1 1 53 50 0.25 0.62 0 cv-navy_sidebar 1 1 71 71 0.20 0.45 0 -cv-nordic_clean 1 1 63 58 0.20 0.57 0 +cv-nordic_clean 1 1 63 58 0.25 0.41 0 cv-orange_ops 1 2 108 5 77.92 77.92 5 -cv-panel 1 1 79 74 0.27 0.49 0 +cv-panel 1 1 79 74 0.75 1.21 0 cv-professional_sidebar 1 1 68 64 0.36 0.58 0 cv-serif_headline 1 1 103 103 0.44 0.88 0 cv-sidebar_portrait 1 1 49 49 0.17 0.31 0 cv-slate_orange 1 1 87 86 0.42 1.02 0 cv-teal_pulse 1 1 57 57 0.22 0.64 0 cv-terracotta_rail 1 1 102 102 0.44 0.94 0 -cv-timeline_minimal 2 2 89 86 0.45 0.50 0 -cv-violet_grid 1 1 80 78 0.22 0.44 0 +cv-timeline_minimal 2 2 89 87 0.45 0.49 0 +cv-violet_grid 1 1 80 78 0.26 0.54 0 invoice-classic 1 1 56 56 0.17 0.32 0 invoice-classic_long 2 2 166 166 0.22 0.27 0 invoice-consulting 1 1 92 92 0.67 1.01 0 invoice-consulting_long 2 2 236 236 0.69 1.04 0 invoice-luma_studio 1 1 97 97 0.12 0.52 2 invoice-luma_studio_long 3 3 192 192 0.20 0.41 2 -invoice-merchant 1 2 94 90 0.12 0.23 0 -invoice-metered 1 1 99 99 0.07 0.70 0 +invoice-merchant 1 2 94 90 0.10 0.18 0 +invoice-metered 1 1 99 99 0.05 0.68 0 invoice-modern 1 1 54 54 0.07 0.20 0 invoice-modern_long 2 2 162 162 0.20 0.27 0 -invoice-obsidian 1 1 81 81 0.48 0.88 0 -invoice-payments 1 1 104 104 0.05 0.26 0 +invoice-obsidian 1 1 81 81 0.34 1.19 0 +invoice-payments 1 1 104 104 0.09 0.23 0 invoice-platform 1 1 111 111 0.27 0.43 0 -invoice-subscription 1 1 81 81 0.28 0.73 0 -invoice-workspace 1 1 90 90 0.18 0.41 0 +invoice-subscription 1 1 81 81 0.62 0.87 0 +invoice-workspace 1 1 90 90 0.21 0.43 0 letter-blue_banner 1 1 10 10 0.42 0.46 0 -letter-boxed_sections 1 1 10 10 0.46 0.70 0 +letter-boxed_sections 1 1 10 10 0.29 0.33 0 letter-centered_headline 1 1 11 11 0.13 0.25 0 letter-classic_serif 1 1 10 10 0.13 0.19 0 letter-compact_mono 1 1 10 8 0.24 0.35 0 letter-editorial_blue 1 1 12 12 0.16 0.22 0 -letter-engineering_resume 1 1 15 15 1.40 1.66 0 +letter-engineering_resume 1 1 15 15 0.19 0.41 0 letter-executive 1 1 12 12 0.18 0.30 0 letter-mint-editorial-letter 1 1 10 10 0.29 0.29 0 -letter-modern_professional 1 1 12 12 0.43 0.43 0 +letter-modern_professional 1 1 12 12 0.03 0.27 0 letter-monogram_sidebar 1 1 12 12 0.23 0.37 0 letter-nordic_clean 1 1 15 15 0.16 0.38 0 -letter-panel 1 1 13 13 0.15 0.21 0 +letter-panel 1 1 13 13 0.13 0.17 0 letter-sidebar_portrait 1 1 12 12 0.43 0.51 0 letter-timeline_minimal 1 1 15 15 0.33 0.53 0 -proposal-editorial 2 2 132 129 44.55 45.38 72 +proposal-editorial 2 2 132 129 44.49 45.38 72 proposal-indigo 1 1 72 70 0.27 0.65 0 -proposal-modern 1 1 44 44 0.50 0.75 0 -proposal-northline 2 2 132 132 0.27 0.57 0 +proposal-modern 1 1 44 44 0.15 0.24 0 +proposal-northline 2 2 132 132 0.27 0.67 0 receipt-modern 1 1 57 57 0.26 0.29 0 rota-cobalt 1 1 154 151 0.23 0.84 0 diff --git a/qa/src/test/resources/docx-fidelity/word-windows-lines.tsv b/qa/src/test/resources/docx-fidelity/word-windows-lines.tsv index 74f5e6e94..4ee861699 100644 --- a/qa/src/test/resources/docx-fidelity/word-windows-lines.tsv +++ b/qa/src/test/resources/docx-fidelity/word-windows-lines.tsv @@ -52,46 +52,46 @@ cv-blue_banner 0:88b226d51fe1 0.54 -0.08 pngdiffing,side-by-sidelayout,ba cv-blue_banner 0:339245d63103 0.60 -0.08 layoutlint(java21,javaparser,spo cv-blue_banner 0:8c87b84946f3 0.82 -0.08 beforetheyshiptoproduction. cv-boxed_sections 0:8f1010120ed6 0.54 0.10 jordanrivera -cv-boxed_sections 0:8d7a2cca3060 -0.16 -0.05 +442055551000|jordan.rivera@exam -cv-boxed_sections 0:b944906ed84c -0.38 0.56 professionalsummary -cv-boxed_sections 0:80cc87fdc4c4 -0.67 -0.08 platformengineerwith10+yearsbuil -cv-boxed_sections 0:bddc0bd093ce -0.62 -0.08 systems.specialisedinhigh-throug -cv-boxed_sections 0:95a43d7b3df0 -0.70 -0.08 snapshot-testedlibrariesthatscal -cv-boxed_sections 0:5f94c50dc5bf -0.33 0.39 technicalskills -cv-boxed_sections 0:eea537278f83 -0.49 -0.08 •languages:java21,kotlin,groovy, -cv-boxed_sections 0:9c2cd7231a53 -0.37 -0.08 •document&print:pdfbox,apachepoi -cv-boxed_sections 0:7bf8639ec5d3 -0.36 -0.08 •layoutengines:customdsldesign,s -cv-boxed_sections 0:8e66776d28d7 -0.33 -0.08 •build&infrastructure:maven,grad -cv-boxed_sections 0:1ed4fc7d7768 -0.32 -0.08 •testing:junit5,assertj,pdfbox-b -cv-boxed_sections 0:26671c309eb9 -0.32 -0.08 •distribution:mavencentral,sonat -cv-boxed_sections 0:68bf0109c6f8 -0.31 0.29 education -cv-boxed_sections 0:0ad1957d6bab -0.29 0.04 msccomputerscience -cv-boxed_sections 0:3fa772117260 -0.36 -0.87 2019-2021 -cv-boxed_sections 0:47ce0218bbea -0.41 -0.08 universityofmanchester -cv-boxed_sections 0:2ffe115b06e5 -0.35 -0.08 distinction.thesis:composablelay -cv-boxed_sections 0:b6749d0b616b -0.33 0.04 bscsoftwareengineering -cv-boxed_sections 0:30f9262640a0 -0.27 -0.87 2015-2019 -cv-boxed_sections 0:89ad9656f393 -0.43 -0.08 imperialcollegelondon -cv-boxed_sections 0:baa173b4a82e -0.25 -0.08 first-classhonours.specialisatio -cv-boxed_sections 0:6d3d5673c39f -0.22 0.04 oraclejavacertification -cv-boxed_sections 0:d40b22f00acb -0.29 -0.87 2023-2024 -cv-boxed_sections 0:2669e1f6d55c -0.34 -0.08 professionaltrack -cv-boxed_sections 0:3857373829c1 -0.28 -0.08 java17platformdeep-dive:records, -cv-boxed_sections 0:2577c0f557b2 -0.27 0.15 projects -cv-boxed_sections 0:b2b029995203 -0.32 -0.08 •graphcompose(java21,pdfbox,mave -cv-boxed_sections 0:67593a76ef70 -0.59 -0.06 declarativejavapdflayoutengine.s -cv-boxed_sections 0:b9292cbd1454 -0.55 -0.06 pipelinesforhiringtoolsandbillin -cv-boxed_sections 0:1b50bb81df5a -0.31 -0.08 •templatestudio(kotlin,composede -cv-boxed_sections 0:836e76daecbf -0.23 -0.06 internaltoolforevaluatingcv,prop -cv-boxed_sections 0:25cdca2beb8b -0.26 -0.08 •layoutlint(java21,javaparser,sp -cv-boxed_sections 0:7488006d7864 -0.54 -0.06 staticanalyserthatflagsfragileau -cv-boxed_sections 0:c4d0c415b4f8 -0.49 -0.06 production. -cv-boxed_sections 0:fb1927f88597 -0.29 -0.08 •chromeforge(java,graphcompose,p -cv-boxed_sections 0:e7e62230eb1f -0.20 -0.06 editorial-magazinedocumenttoolki -cv-boxed_sections 0:c2f296ef30a3 -0.20 0.54 professionalexperience -cv-boxed_sections 0:a76f47480818 -0.18 0.04 seniorplatformengineer -cv-boxed_sections 0:060300b18051 -0.25 0.07 2024-present -cv-boxed_sections 0:f890faef907f -0.28 -0.08 northwindsystems +cv-boxed_sections 0:8d7a2cca3060 0.20 -0.05 +442055551000|jordan.rivera@exam +cv-boxed_sections 0:b944906ed84c 0.34 0.56 professionalsummary +cv-boxed_sections 0:80cc87fdc4c4 0.05 -0.08 platformengineerwith10+yearsbuil +cv-boxed_sections 0:bddc0bd093ce 0.10 -0.08 systems.specialisedinhigh-throug +cv-boxed_sections 0:95a43d7b3df0 0.02 -0.08 snapshot-testedlibrariesthatscal +cv-boxed_sections 0:5f94c50dc5bf 0.27 0.39 technicalskills +cv-boxed_sections 0:eea537278f83 0.23 -0.08 •languages:java21,kotlin,groovy, +cv-boxed_sections 0:9c2cd7231a53 0.23 -0.08 •document&print:pdfbox,apachepoi +cv-boxed_sections 0:7bf8639ec5d3 0.24 -0.08 •layoutengines:customdsldesign,s +cv-boxed_sections 0:8e66776d28d7 0.27 -0.08 •build&infrastructure:maven,grad +cv-boxed_sections 0:1ed4fc7d7768 0.28 -0.08 •testing:junit5,assertj,pdfbox-b +cv-boxed_sections 0:26671c309eb9 0.28 -0.08 •distribution:mavencentral,sonat +cv-boxed_sections 0:68bf0109c6f8 0.41 0.29 education +cv-boxed_sections 0:0ad1957d6bab 0.43 0.04 msccomputerscience +cv-boxed_sections 0:3fa772117260 0.36 -0.87 2019-2021 +cv-boxed_sections 0:47ce0218bbea 0.31 -0.08 universityofmanchester +cv-boxed_sections 0:2ffe115b06e5 0.37 -0.08 distinction.thesis:composablelay +cv-boxed_sections 0:b6749d0b616b 0.39 0.04 bscsoftwareengineering +cv-boxed_sections 0:30f9262640a0 0.33 -0.87 2015-2019 +cv-boxed_sections 0:89ad9656f393 0.29 -0.08 imperialcollegelondon +cv-boxed_sections 0:baa173b4a82e 0.35 -0.08 first-classhonours.specialisatio +cv-boxed_sections 0:6d3d5673c39f 0.50 0.04 oraclejavacertification +cv-boxed_sections 0:d40b22f00acb 0.43 -0.87 2023-2024 +cv-boxed_sections 0:2669e1f6d55c 0.38 -0.08 professionaltrack +cv-boxed_sections 0:3857373829c1 0.44 -0.08 java17platformdeep-dive:records, +cv-boxed_sections 0:2577c0f557b2 0.45 0.15 projects +cv-boxed_sections 0:b2b029995203 0.40 -0.08 •graphcompose(java21,pdfbox,mave +cv-boxed_sections 0:67593a76ef70 0.13 -0.06 declarativejavapdflayoutengine.s +cv-boxed_sections 0:b9292cbd1454 0.17 -0.06 pipelinesforhiringtoolsandbillin +cv-boxed_sections 0:1b50bb81df5a 0.41 -0.08 •templatestudio(kotlin,composede +cv-boxed_sections 0:836e76daecbf 0.37 -0.06 internaltoolforevaluatingcv,prop +cv-boxed_sections 0:25cdca2beb8b 0.46 -0.08 •layoutlint(java21,javaparser,sp +cv-boxed_sections 0:7488006d7864 0.18 -0.06 staticanalyserthatflagsfragileau +cv-boxed_sections 0:c4d0c415b4f8 0.23 -0.06 production. +cv-boxed_sections 0:fb1927f88597 0.43 -0.08 •chromeforge(java,graphcompose,p +cv-boxed_sections 0:e7e62230eb1f 0.40 -0.06 editorial-magazinedocumenttoolki +cv-boxed_sections 0:c2f296ef30a3 0.52 0.54 professionalexperience +cv-boxed_sections 0:a76f47480818 0.54 0.04 seniorplatformengineer +cv-boxed_sections 0:060300b18051 0.47 0.07 2024-present +cv-boxed_sections 0:f890faef907f 0.44 -0.08 northwindsystems cv-boxed_sections 1:49faf14f1f56 -0.06 -0.08 ledthereusabledocument-generatio cv-boxed_sections 1:6bd3f168e89e -0.01 -0.08 maintenancetimeby70%byretiringpe cv-boxed_sections 1:daf65306b3b6 0.25 0.04 softwareengineer @@ -174,123 +174,123 @@ cv-charcoal_gold 0:92966f349443 -0.14 0.13 london,unitedkingdom cv-charcoal_gold 0:42535367bd3c -0.11 0.13 anastasiasmith.com cv-charcoal_gold 0:d5d2c85de2b9 -0.11 0.13 linkedin.com/in/anastasiasmith cv-charcoal_gold 0:32c1cf49a2fe -0.28 -0.80 skills -cv-charcoal_gold 0:340455fbac25 -0.15 0.02 projectmanagement +cv-charcoal_gold 0:340455fbac25 -0.27 0.02 projectmanagement cv-charcoal_gold 0:03cd52ebdc67 -0.19 0.02 budgeting&forecasting -cv-charcoal_gold 0:115925c1b96b -0.11 0.02 stakeholdercommunication -cv-charcoal_gold 0:4e321f38b222 -0.15 0.02 riskmanagement -cv-charcoal_gold 0:2f594f65f16c -0.07 0.02 dataanalysis -cv-charcoal_gold 0:b08c44dac044 -0.09 0.02 processimprovement -cv-charcoal_gold 0:c7b5692b2d27 -0.13 0.02 microsoftexcel -cv-charcoal_gold 0:2e2c6b2f5ad9 -0.05 0.02 powerbi -cv-charcoal_gold 0:f73b1d7d3bc6 -0.09 0.02 jira/confluence -cv-charcoal_gold 0:b011cfad056f -0.13 0.02 agilemethodologies -cv-charcoal_gold 0:6cb574fa10b6 -0.10 -0.80 languages -cv-charcoal_gold 0:b6234d2ea0d6 0.07 0.04 english -cv-charcoal_gold 0:bef32d2c315a 0.07 -0.05 native -cv-charcoal_gold 0:bef32d2c315a#1 -0.03 -0.05 native -cv-charcoal_gold 0:aa304b5d1d72 -0.03 0.04 russian -cv-charcoal_gold 0:21bb36ad0638 0.02 0.04 french -cv-charcoal_gold 0:23ed645595d6 0.02 -0.05 b2–upperintermediate -cv-charcoal_gold 0:28561c6b68fc 0.04 0.04 german -cv-charcoal_gold 0:3cb3c2736bad 0.04 -0.05 a2–basic -cv-charcoal_gold 0:68bf0109c6f8 -0.03 -0.80 education -cv-charcoal_gold 0:48f12eb2ea0d -0.02 0.31 mscprojectmanagement -cv-charcoal_gold 0:ede0c8c47a1f -0.06 0.00 universitycollegelondon -cv-charcoal_gold 0:fc3f0389b9de 0.02 0.00 2018–2019 -cv-charcoal_gold 0:66cb4ff79ee1 0.00 0.31 bscbusinessadministration -cv-charcoal_gold 0:8826393fc0f0 -0.04 0.00 king'scollegelondon -cv-charcoal_gold 0:c7d18ae8c50d -0.06 0.00 2014–2017 +cv-charcoal_gold 0:115925c1b96b -0.23 0.02 stakeholdercommunication +cv-charcoal_gold 0:4e321f38b222 -0.27 0.02 riskmanagement +cv-charcoal_gold 0:2f594f65f16c -0.19 0.02 dataanalysis +cv-charcoal_gold 0:b08c44dac044 -0.21 0.02 processimprovement +cv-charcoal_gold 0:c7b5692b2d27 -0.25 0.02 microsoftexcel +cv-charcoal_gold 0:2e2c6b2f5ad9 -0.17 0.02 powerbi +cv-charcoal_gold 0:f73b1d7d3bc6 -0.21 0.02 jira/confluence +cv-charcoal_gold 0:b011cfad056f -0.25 0.02 agilemethodologies +cv-charcoal_gold 0:6cb574fa10b6 -0.22 -0.80 languages +cv-charcoal_gold 0:b6234d2ea0d6 -0.17 0.04 english +cv-charcoal_gold 0:bef32d2c315a -0.17 -0.05 native +cv-charcoal_gold 0:bef32d2c315a#1 -0.15 -0.05 native +cv-charcoal_gold 0:aa304b5d1d72 -0.15 0.04 russian +cv-charcoal_gold 0:21bb36ad0638 -0.10 0.04 french +cv-charcoal_gold 0:23ed645595d6 -0.10 -0.05 b2–upperintermediate +cv-charcoal_gold 0:28561c6b68fc -0.20 0.04 german +cv-charcoal_gold 0:3cb3c2736bad -0.20 -0.05 a2–basic +cv-charcoal_gold 0:68bf0109c6f8 -0.15 -0.80 education +cv-charcoal_gold 0:48f12eb2ea0d -0.14 0.31 mscprojectmanagement +cv-charcoal_gold 0:ede0c8c47a1f -0.18 0.00 universitycollegelondon +cv-charcoal_gold 0:fc3f0389b9de -0.22 0.00 2018–2019 +cv-charcoal_gold 0:66cb4ff79ee1 -0.24 0.31 bscbusinessadministration +cv-charcoal_gold 0:8826393fc0f0 -0.28 0.00 king'scollegelondon +cv-charcoal_gold 0:c7d18ae8c50d -0.18 0.00 2014–2017 cv-charcoal_gold 0:3acba0d7b5dc -0.29 0.00 projectmanager -cv-charcoal_gold 0:3acba0d7b5dc#1 0.05 0.02 projectmanager +cv-charcoal_gold 0:3acba0d7b5dc#1 -0.07 0.02 projectmanager cv-charcoal_gold 0:f54e0195601a 0.02 0.00 results-drivenprojectmanagerwith cv-charcoal_gold 0:7a0497cef9c6 0.08 0.00 teamsanddeliveringcomplexproject cv-charcoal_gold 0:c38f1902ece8 0.44 0.00 skilledinagileandwaterfallmethod cv-charcoal_gold 0:ca94787c6c7a -0.34 0.00 management.passionateaboutdrivin cv-charcoal_gold 0:53e5e7c5a884 -0.26 -0.72 experience -cv-charcoal_gold 0:086c0e036e67 -0.11 0.00 2021–present -cv-charcoal_gold 0:eddc2d311872 -0.13 0.02 seniorprojectmanager -cv-charcoal_gold 0:243953e20dc4 -0.06 0.02 digitalsolutionsltd·london,uk -cv-charcoal_gold 0:7fde5861c84b -0.03 0.02 •managecross-functionalteamsofup -cv-charcoal_gold 0:80c76af1fe2a 0.05 0.02 •implementagilepracticesthatimpr -cv-charcoal_gold 0:b6bb33b79f44 0.01 0.02 •buildstrongclientrelationshipsa +cv-charcoal_gold 0:086c0e036e67 -0.23 0.00 2021–present +cv-charcoal_gold 0:eddc2d311872 -0.25 0.02 seniorprojectmanager +cv-charcoal_gold 0:243953e20dc4 -0.18 0.02 digitalsolutionsltd·london,uk +cv-charcoal_gold 0:7fde5861c84b -0.15 0.02 •managecross-functionalteamsofup +cv-charcoal_gold 0:80c76af1fe2a -0.07 0.02 •implementagilepracticesthatimpr +cv-charcoal_gold 0:b6bb33b79f44 -0.11 0.02 •buildstrongclientrelationshipsa cv-charcoal_gold 0:6c39082d9294 -0.05 0.00 2019–2021 -cv-charcoal_gold 0:46df57ef8321 0.12 0.02 innovatechsystems·london,uk -cv-charcoal_gold 0:271b01626043 0.05 0.02 •delivered12+projectsacrossitand -cv-charcoal_gold 0:77dd7c2ad6ae 0.13 0.02 •monitoredbudgets,timelines,andr -cv-charcoal_gold 0:bf8278cd4edc 0.11 0.02 •identifiedrisksandimplementedmi -cv-charcoal_gold 0:2773f92777d7 0.19 0.02 •achieved98%on-timeprojectdelive -cv-charcoal_gold 0:ad564a6ee91d 0.13 0.00 2017–2019 -cv-charcoal_gold 0:e085ad3a0d32 0.11 0.02 projectcoordinator -cv-charcoal_gold 0:6ac382583801 0.18 0.02 globalbusinessservices·london,uk -cv-charcoal_gold 0:77aec5bb6b7f 0.23 0.02 •supportedprojectmanagersinplann -cv-charcoal_gold 0:38dafe4a1765 0.19 0.02 •preparedreports,dashboards,andd -cv-charcoal_gold 0:5c95a9041b72 0.27 0.02 •coordinatedmeetingsandtrackedac -cv-charcoal_gold 0:f0d87e2131e2 0.23 0.02 •improvedinternalprocessesandpro -cv-charcoal_gold 0:e831beb04c00 0.24 0.12 certifications -cv-charcoal_gold 0:93a7ba535da0 0.38 0.08 pmp®certification -cv-charcoal_gold 0:0f9f6d10bfa3 0.44 0.08 projectmanagementinstitute -cv-charcoal_gold 0:73a2af8864fc 0.36 0.08 2020 -cv-charcoal_gold 0:73a2af8864fc#1 0.48 0.03 2020 -cv-charcoal_gold 0:043092900ed5 0.38 0.08 prince2®foundation -cv-charcoal_gold 0:544a764703d6 0.44 0.08 axelos -cv-charcoal_gold 0:023e33504ab9 0.48 0.08 2019 -cv-charcoal_gold 0:023e33504ab9#1 0.48 0.08 2019 -cv-charcoal_gold 0:83cd2e790f6a 0.38 0.08 agilepm®foundation -cv-charcoal_gold 0:0005e5872534 0.44 0.08 apmginternational -cv-charcoal_gold 0:6ee18b42fbf1 0.24 0.14 achievements -cv-charcoal_gold 0:3f06e4a3eb33 0.38 0.03 excellenceindeliveryaward -cv-charcoal_gold 0:0c373352626d 0.44 0.03 digitalsolutionsltd -cv-charcoal_gold 0:d398b29d3dbb 0.36 0.03 2023 -cv-charcoal_gold 0:92cb97e6b786 0.38 0.03 processimprovementinitiative -cv-charcoal_gold 0:6517b58450f7 0.44 0.03 increasedefficiencyby30% -cv-charcoal_gold 0:b1ab1e892617 0.48 0.03 2022 -cv-charcoal_gold 0:c2f5106fbd5a 0.38 0.03 topperformer -cv-charcoal_gold 0:058521fbf0d1 0.44 0.03 innovatechsystems -cv-charcoal_gold 0:3def82282260 0.40 -0.72 technicaltools -cv-charcoal_gold 0:eb04bd42c7fb 0.46 -1.03 microsoft365|jira|confluence|asa +cv-charcoal_gold 0:46df57ef8321 0.00 0.02 innovatechsystems·london,uk +cv-charcoal_gold 0:271b01626043 -0.07 0.02 •delivered12+projectsacrossitand +cv-charcoal_gold 0:77dd7c2ad6ae 0.01 0.02 •monitoredbudgets,timelines,andr +cv-charcoal_gold 0:bf8278cd4edc -0.01 0.02 •identifiedrisksandimplementedmi +cv-charcoal_gold 0:2773f92777d7 0.07 0.02 •achieved98%on-timeprojectdelive +cv-charcoal_gold 0:ad564a6ee91d 0.01 0.00 2017–2019 +cv-charcoal_gold 0:e085ad3a0d32 -0.01 0.02 projectcoordinator +cv-charcoal_gold 0:6ac382583801 0.06 0.02 globalbusinessservices·london,uk +cv-charcoal_gold 0:77aec5bb6b7f 0.11 0.02 •supportedprojectmanagersinplann +cv-charcoal_gold 0:38dafe4a1765 0.07 0.02 •preparedreports,dashboards,andd +cv-charcoal_gold 0:5c95a9041b72 0.15 0.02 •coordinatedmeetingsandtrackedac +cv-charcoal_gold 0:f0d87e2131e2 0.11 0.02 •improvedinternalprocessesandpro +cv-charcoal_gold 0:e831beb04c00 0.12 0.12 certifications +cv-charcoal_gold 0:93a7ba535da0 0.14 0.08 pmp®certification +cv-charcoal_gold 0:0f9f6d10bfa3 0.20 0.08 projectmanagementinstitute +cv-charcoal_gold 0:73a2af8864fc 0.24 0.08 2020 +cv-charcoal_gold 0:73a2af8864fc#1 0.24 0.03 2020 +cv-charcoal_gold 0:043092900ed5 0.14 0.08 prince2®foundation +cv-charcoal_gold 0:544a764703d6 0.20 0.08 axelos +cv-charcoal_gold 0:023e33504ab9 0.24 0.08 2019 +cv-charcoal_gold 0:023e33504ab9#1 0.24 0.08 2019 +cv-charcoal_gold 0:83cd2e790f6a 0.26 0.08 agilepm®foundation +cv-charcoal_gold 0:0005e5872534 0.20 0.08 apmginternational +cv-charcoal_gold 0:6ee18b42fbf1 0.12 0.14 achievements +cv-charcoal_gold 0:3f06e4a3eb33 0.14 0.03 excellenceindeliveryaward +cv-charcoal_gold 0:0c373352626d 0.20 0.03 digitalsolutionsltd +cv-charcoal_gold 0:d398b29d3dbb 0.24 0.03 2023 +cv-charcoal_gold 0:92cb97e6b786 0.14 0.03 processimprovementinitiative +cv-charcoal_gold 0:6517b58450f7 0.20 0.03 increasedefficiencyby30% +cv-charcoal_gold 0:b1ab1e892617 0.24 0.03 2022 +cv-charcoal_gold 0:c2f5106fbd5a 0.26 0.03 topperformer +cv-charcoal_gold 0:058521fbf0d1 0.20 0.03 innovatechsystems +cv-charcoal_gold 0:3def82282260 0.16 -0.72 technicaltools +cv-charcoal_gold 0:eb04bd42c7fb 0.22 -1.03 microsoft365|jira|confluence|asa cv-classic_serif 0:8f1010120ed6 0.19 0.09 jordanrivera cv-classic_serif 0:8d7a2cca3060 0.27 -0.53 +442055551000|jordan.rivera@exam cv-classic_serif 0:3c69d6bb4892 0.28 1.37 professionalprofile -cv-classic_serif 0:32c1cf49a2fe 0.19 0.04 skills -cv-classic_serif 0:873a24d153c8 0.13 0.04 languages:java21,kotlin,groovy,p -cv-classic_serif 0:05e907ef2b18 0.05 0.04 document&print:pdfbox,apachepoi( -cv-classic_serif 0:76656a8a6621 -0.04 0.04 layoutengines:customdsldesign,se -cv-classic_serif 0:1cd141fef347 0.00 0.04 build&infrastructure:maven,gradl -cv-classic_serif 0:181ddda7f959 -0.06 0.04 testing:junit5,assertj,pdfbox-ba -cv-classic_serif 0:c40c656d9558 -0.02 0.04 distribution:mavencentral,sonaty -cv-classic_serif 0:53e5e7c5a884 0.04 0.04 experience -cv-classic_serif 0:a76f47480818 0.13 0.04 seniorplatformengineer -cv-classic_serif 0:060300b18051 0.05 0.07 2024-present -cv-classic_serif 0:f890faef907f 0.06 0.04 northwindsystems -cv-classic_serif 0:49faf14f1f56 -0.25 0.04 ledthereusabledocument-generatio -cv-classic_serif 0:6bd3f168e89e -0.18 0.04 maintenancetimeby70%byretiringpe -cv-classic_serif 0:daf65306b3b6 0.15 0.04 softwareengineer -cv-classic_serif 0:e7cc1822c6dc 0.07 1.06 2021-2024 -cv-classic_serif 0:998c1a985022 0.08 0.04 brightleaflabs -cv-classic_serif 0:e55664011cda -0.24 0.04 builtbackendservicesandproductio -cv-classic_serif 0:e80236b6d2b1 -0.15 0.04 itexttoacustomlayoutengine,elimi -cv-classic_serif 0:41bb54fbae8d 0.18 0.04 backendengineer -cv-classic_serif 0:3fa772117260 0.10 1.06 2019-2021 -cv-classic_serif 0:3fa772117260#1 0.19 1.06 2019-2021 -cv-classic_serif 0:ef148f221e31 0.11 0.04 helixprintco -cv-classic_serif 0:9d31a6bfbc69 -0.20 0.04 maintainedahigh-volumeinvoice-pr -cv-classic_serif 0:03af8a628309 -0.13 0.04 change. -cv-classic_serif 0:2577c0f557b2 0.11 0.04 projects -cv-classic_serif 0:0f2c67872251 0.16 0.04 graphcompose(java21,pdfbox,maven -cv-classic_serif 0:67593a76ef70 -0.25 0.04 declarativejavapdflayoutengine.s -cv-classic_serif 0:b9292cbd1454 -0.06 0.04 pipelinesforhiringtoolsandbillin -cv-classic_serif 0:d73d02174dc9 0.10 0.04 templatestudio(kotlin,composedes -cv-classic_serif 0:836e76daecbf 0.20 0.04 internaltoolforevaluatingcv,prop -cv-classic_serif 0:542ec793b5b1 0.12 0.04 layoutlint(java21,javaparser,spo -cv-classic_serif 0:dc31b6a18325 0.19 0.04 staticanalyserthatflagsfragileau -cv-classic_serif 0:ee180ea1e0a5 0.11 0.04 chromeforge(java,graphcompose,pa -cv-classic_serif 0:e7e62230eb1f 0.18 0.04 editorial-magazinedocumenttoolki -cv-classic_serif 0:68bf0109c6f8 0.18 0.04 education -cv-classic_serif 0:0ad1957d6bab 0.15 0.04 msccomputerscience -cv-classic_serif 0:47ce0218bbea 0.20 0.04 universityofmanchester -cv-classic_serif 0:2ffe115b06e5 0.25 0.04 distinction.thesis:composablelay -cv-classic_serif 0:b6749d0b616b 0.23 0.04 bscsoftwareengineering -cv-classic_serif 0:30f9262640a0 0.15 1.06 2015-2019 +cv-classic_serif 0:32c1cf49a2fe 0.43 0.04 skills +cv-classic_serif 0:873a24d153c8 0.37 0.04 languages:java21,kotlin,groovy,p +cv-classic_serif 0:05e907ef2b18 0.29 0.04 document&print:pdfbox,apachepoi( +cv-classic_serif 0:76656a8a6621 0.32 0.04 layoutengines:customdsldesign,se +cv-classic_serif 0:1cd141fef347 0.24 0.04 build&infrastructure:maven,gradl +cv-classic_serif 0:181ddda7f959 0.30 0.04 testing:junit5,assertj,pdfbox-ba +cv-classic_serif 0:c40c656d9558 0.22 0.04 distribution:mavencentral,sonaty +cv-classic_serif 0:53e5e7c5a884 0.40 0.04 experience +cv-classic_serif 0:a76f47480818 0.37 0.04 seniorplatformengineer +cv-classic_serif 0:060300b18051 0.29 0.07 2024-present +cv-classic_serif 0:f890faef907f 0.30 0.04 northwindsystems +cv-classic_serif 0:49faf14f1f56 -0.01 0.04 ledthereusabledocument-generatio +cv-classic_serif 0:6bd3f168e89e 0.06 0.04 maintenancetimeby70%byretiringpe +cv-classic_serif 0:daf65306b3b6 0.39 0.04 softwareengineer +cv-classic_serif 0:e7cc1822c6dc 0.31 1.06 2021-2024 +cv-classic_serif 0:998c1a985022 0.32 0.04 brightleaflabs +cv-classic_serif 0:e55664011cda 0.00 0.04 builtbackendservicesandproductio +cv-classic_serif 0:e80236b6d2b1 0.09 0.04 itexttoacustomlayoutengine,elimi +cv-classic_serif 0:41bb54fbae8d 0.42 0.04 backendengineer +cv-classic_serif 0:3fa772117260 0.34 1.06 2019-2021 +cv-classic_serif 0:3fa772117260#1 0.43 1.06 2019-2021 +cv-classic_serif 0:ef148f221e31 0.35 0.04 helixprintco +cv-classic_serif 0:9d31a6bfbc69 0.04 0.04 maintainedahigh-volumeinvoice-pr +cv-classic_serif 0:03af8a628309 0.11 0.04 change. +cv-classic_serif 0:2577c0f557b2 0.47 0.04 projects +cv-classic_serif 0:0f2c67872251 0.40 0.04 graphcompose(java21,pdfbox,maven +cv-classic_serif 0:67593a76ef70 -0.01 0.04 declarativejavapdflayoutengine.s +cv-classic_serif 0:b9292cbd1454 0.18 0.04 pipelinesforhiringtoolsandbillin +cv-classic_serif 0:d73d02174dc9 0.34 0.04 templatestudio(kotlin,composedes +cv-classic_serif 0:836e76daecbf 0.44 0.04 internaltoolforevaluatingcv,prop +cv-classic_serif 0:542ec793b5b1 0.36 0.04 layoutlint(java21,javaparser,spo +cv-classic_serif 0:dc31b6a18325 0.43 0.04 staticanalyserthatflagsfragileau +cv-classic_serif 0:ee180ea1e0a5 0.35 0.04 chromeforge(java,graphcompose,pa +cv-classic_serif 0:e7e62230eb1f 0.42 0.04 editorial-magazinedocumenttoolki +cv-classic_serif 0:68bf0109c6f8 0.42 0.04 education +cv-classic_serif 0:0ad1957d6bab 0.51 0.04 msccomputerscience +cv-classic_serif 0:47ce0218bbea 0.44 0.04 universityofmanchester +cv-classic_serif 0:2ffe115b06e5 0.49 0.04 distinction.thesis:composablelay +cv-classic_serif 0:b6749d0b616b 0.47 0.04 bscsoftwareengineering +cv-classic_serif 0:30f9262640a0 0.51 1.06 2015-2019 cv-classic_serif 1:89ad9656f393 0.24 0.04 imperialcollegelondon cv-classic_serif 1:baa173b4a82e 0.29 0.04 first-classhonours.specialisatio cv-classic_serif 1:6d3d5673c39f 0.25 0.04 oraclejavacertification @@ -332,34 +332,34 @@ cv-compact_mono 0:8051a4b5e34f 0.95 -0.04 opensource:maintainerofgraphcomp cv-compact_mono 0:08c2e869a75b 0.98 -0.04 regularcontributortopdfboxissuet cv-compact_mono 0:12dcd1343975 0.90 -0.04 speaking:jvmsummit2024,devoxxuk2 cv-compact_mono 0:3aea7f90f8ed 0.93 -0.04 —bothondeclarativedocumentlayout -cv-compact_mono 0:1900eab6c028 0.51 0.06 profile -cv-compact_mono 0:3828b9718a0d -0.16 0.06 platformengineerwith10+yearsbuil -cv-compact_mono 0:f6b5e93ccadd -0.20 0.06 engines,anddeveloper-facingtempl -cv-compact_mono 0:927ef106776a -0.12 0.06 semanticauthoringdsls,andturning -cv-compact_mono 0:330fcb75ed52 -0.16 0.06 librariesthatscale. -cv-compact_mono 0:53e5e7c5a884 0.21 0.06 experience -cv-compact_mono 0:c9efb118bfda -0.17 0.06 seniorplatformengineer,northwind -cv-compact_mono 0:64c4b52dceb1 -0.36 0.06 ledthereusabledocument-generatio -cv-compact_mono 0:1f193cd1d987 -0.36 0.06 productteams.reducedtemplatemain -cv-compact_mono 0:9ccc3e904e5a -0.33 0.06 favourofonecanonicalengine. -cv-compact_mono 0:e21e4e47835a -0.08 0.06 softwareengineer,brightleaflabs| -cv-compact_mono 0:0cdd48f05f9d -0.27 0.06 builtbackendservicesandproductio -cv-compact_mono 0:e48f1e2c853d -0.27 0.06 permonth.drovethemigrationfromit -cv-compact_mono 0:b78a9a72ca9a -0.27 0.06 andcuttingp99renderlatencyfrom1. -cv-compact_mono 0:9f5d87c00954 -0.02 0.06 backendengineer,helixprintco|201 -cv-compact_mono 0:a485c37fe7ea -0.21 0.06 maintainedahigh-volumeinvoice-pr -cv-compact_mono 0:5a136b6b9d8c -0.21 0.06 testharnessthatgatedeverytemplat -cv-compact_mono 0:d94eccbb1fbe 0.06 0.06 selectedprojects -cv-compact_mono 0:0059a3aac61e -0.56 0.06 graphcompose(java21,pdfbox,maven -cv-compact_mono 0:18b7f8c840e4 -0.55 0.06 dsl,slot-basedtemplates,snapshot -cv-compact_mono 0:d36f78e88fe0 -0.53 0.06 forhiringtoolsandbillingsystems. -cv-compact_mono 0:55e119878845 -0.38 0.06 templatestudio(kotlin,composedes -cv-compact_mono 0:c7b83853442b -0.37 0.06 proposal,andinvoiceoutputacross1 -cv-compact_mono 0:6b844249c695 -0.35 0.06 freezing. -cv-compact_mono 0:ab89138286bb -0.34 0.06 layoutlint(java21,javaparser,spo -cv-compact_mono 0:2c506ce69aa6 -0.33 0.06 nestedrows,untypedoffsets,implic -cv-compact_mono 0:6793d28e9783 -0.32 0.06 chromeforge(java,graphcompose,pa -cv-compact_mono 0:e3cfea265b3b -0.31 0.06 graphcompose:cinematiccovers,pul +cv-compact_mono 0:1900eab6c028 0.27 0.06 profile +cv-compact_mono 0:3828b9718a0d -0.40 0.06 platformengineerwith10+yearsbuil +cv-compact_mono 0:f6b5e93ccadd -0.32 0.06 engines,anddeveloper-facingtempl +cv-compact_mono 0:927ef106776a -0.36 0.06 semanticauthoringdsls,andturning +cv-compact_mono 0:330fcb75ed52 -0.28 0.06 librariesthatscale. +cv-compact_mono 0:53e5e7c5a884 0.45 0.06 experience +cv-compact_mono 0:c9efb118bfda 0.07 0.06 seniorplatformengineer,northwind +cv-compact_mono 0:64c4b52dceb1 -0.24 0.06 ledthereusabledocument-generatio +cv-compact_mono 0:1f193cd1d987 -0.24 0.06 productteams.reducedtemplatemain +cv-compact_mono 0:9ccc3e904e5a -0.21 0.06 favourofonecanonicalengine. +cv-compact_mono 0:e21e4e47835a 0.04 0.06 softwareengineer,brightleaflabs| +cv-compact_mono 0:0cdd48f05f9d -0.15 0.06 builtbackendservicesandproductio +cv-compact_mono 0:e48f1e2c853d -0.15 0.06 permonth.drovethemigrationfromit +cv-compact_mono 0:b78a9a72ca9a -0.15 0.06 andcuttingp99renderlatencyfrom1. +cv-compact_mono 0:9f5d87c00954 0.10 0.06 backendengineer,helixprintco|201 +cv-compact_mono 0:a485c37fe7ea -0.09 0.06 maintainedahigh-volumeinvoice-pr +cv-compact_mono 0:5a136b6b9d8c -0.09 0.06 testharnessthatgatedeverytemplat +cv-compact_mono 0:d94eccbb1fbe 0.66 0.06 selectedprojects +cv-compact_mono 0:0059a3aac61e -0.08 0.06 graphcompose(java21,pdfbox,maven +cv-compact_mono 0:18b7f8c840e4 -0.07 0.06 dsl,slot-basedtemplates,snapshot +cv-compact_mono 0:d36f78e88fe0 0.07 0.06 forhiringtoolsandbillingsystems. +cv-compact_mono 0:55e119878845 0.10 0.06 templatestudio(kotlin,composedes +cv-compact_mono 0:c7b83853442b 0.11 0.06 proposal,andinvoiceoutputacross1 +cv-compact_mono 0:6b844249c695 0.13 0.06 freezing. +cv-compact_mono 0:ab89138286bb 0.14 0.06 layoutlint(java21,javaparser,spo +cv-compact_mono 0:2c506ce69aa6 0.15 0.06 nestedrows,untypedoffsets,implic +cv-compact_mono 0:6793d28e9783 0.16 0.06 chromeforge(java,graphcompose,pa +cv-compact_mono 0:e3cfea265b3b 0.17 0.06 graphcompose:cinematiccovers,pul cv-editorial_blue 0:8f1010120ed6 0.40 -0.01 jordanrivera cv-editorial_blue 0:2d58f0cadc2d 0.31 -0.05 platformengineer cv-editorial_blue 0:1b28eb6a9a2e 0.18 -0.02 +442055551000-london,uk @@ -449,56 +449,56 @@ cv-engineering_resume 0:89674e6f130e -0.11 0.16 +442055551000 cv-engineering_resume 0:e0f850305ded -0.07 0.05 jordan.rivera@example.com cv-engineering_resume 0:84308bea4540 -0.15 0.92 linkedin cv-engineering_resume 0:c0b0109d9439 -0.11 0.79 github -cv-engineering_resume 0:32c1cf49a2fe -0.54 0.00 skills -cv-engineering_resume 0:873a24d153c8 -0.36 0.00 languages:java21,kotlin,groovy,p -cv-engineering_resume 0:db84150190bb -0.66 0.00 document&print:pdfbox,apachepoi -cv-engineering_resume 0:69d03fef7130 -0.64 0.00 (docx/xlsx),itext,postscript,icc -cv-engineering_resume 0:d52fd337f016 -0.62 0.00 profiles -cv-engineering_resume 0:f93032b34754 -0.56 0.00 layoutengines:customdsldesign,se -cv-engineering_resume 0:2d6fa255ba3a -0.54 0.00 layouttrees,pagination,snapshott -cv-engineering_resume 0:f274537aaf2c -0.52 0.00 regression -cv-engineering_resume 0:45fcec9fa26d -0.58 0.00 build&infrastructure:maven,gradl -cv-engineering_resume 0:33ddf84f4bab -0.56 0.00 actions,jitpack,docker -cv-engineering_resume 0:af23376e2ec2 -0.50 0.00 testing:junit5,assertj,pdfbox-ba -cv-engineering_resume 0:a8c30cabf363 -0.48 0.00 diff,layout-graphsnapshots,mutat -cv-engineering_resume 0:7c093617a679 -0.58 0.00 (pitest) -cv-engineering_resume 0:11ca7190fe83 -0.49 0.00 distribution:mavencentral,sonaty -cv-engineering_resume 0:768ad260251b -0.47 0.00 gpgsigning,jitpack,semanticversi -cv-engineering_resume 0:d43c8bd5797a -0.45 0.00 discipline -cv-engineering_resume 0:68bf0109c6f8 -0.29 0.00 education -cv-engineering_resume 0:5f9c672fafaf -0.23 0.00 msccomputerscience/2019-2021 -cv-engineering_resume 0:141310eca6fb -0.19 0.00 bscsoftwareengineering/2015-2019 -cv-engineering_resume 0:608c03298f47 -0.27 0.00 oraclejavacertification/2023-202 -cv-engineering_resume 0:41ffd8b76afc -0.37 0.00 details -cv-engineering_resume 0:ecc25e73b19b -0.55 0.00 languages:english(fluent),german -cv-engineering_resume 0:ac7f0ee6a49e -0.53 0.00 (intermediate),spanish(basic) -cv-engineering_resume 0:970ca9d789c2 -0.47 0.00 workeligibility:eligibletoworkin -cv-engineering_resume 0:0735680e2596 -0.45 0.00 theeu -cv-engineering_resume 0:e8256e23459a -1.54 0.05 engineeringprofile -cv-engineering_resume 0:e9b75496bfb4 -1.59 0.05 platformengineerwith10+yearsbuil -cv-engineering_resume 0:866be9f7a132 -1.53 0.05 developer-facingtemplatesystems. -cv-engineering_resume 0:82c1650fbfe8 -1.59 0.05 dsls,andturningbrittleproduction -cv-engineering_resume 0:53e5e7c5a884 -1.60 0.09 experience -cv-engineering_resume 0:4977534824cc -1.46 0.01 seniorplatformengineer/2024-pres -cv-engineering_resume 0:f890faef907f -1.43 0.01 northwindsystems -cv-engineering_resume 0:0bf7eb0b1058 -1.68 0.01 ledthereusabledocument-generatio -cv-engineering_resume 0:d69cae607226 -1.50 0.01 teams.reducedtemplatemaintenance -cv-engineering_resume 0:bdea17333528 -1.56 0.01 engine. -cv-engineering_resume 0:7033b2988e4d -1.33 0.01 softwareengineer/2021-2024 -cv-engineering_resume 0:998c1a985022 -1.30 0.01 brightleaflabs -cv-engineering_resume 0:e77e909f6ff5 -1.55 0.01 builtbackendservicesandproductio -cv-engineering_resume 0:97c59b2fdb55 -1.49 0.01 drovethemigrationfromitexttoacus -cv-engineering_resume 0:2c2b19cf214d -1.43 0.01 latencyfrom1.4sto380ms. -cv-engineering_resume 0:8b5abdc8c0d7 -1.49 0.09 technicalevidence -cv-engineering_resume 0:e2fbf67cb588 -1.02 0.01 graphcompose(java21,pdfbox,maven -cv-engineering_resume 0:eb5950729749 -1.06 0.01 templates,snapshottesting.powers -cv-engineering_resume 0:81c8132f9792 -1.16 0.01 systems.(opensource) -cv-engineering_resume 0:643428f0ebf8 -1.04 0.01 templatestudio(kotlin,composedes -cv-engineering_resume 0:c259a0e7581e -1.32 0.01 invoiceoutputacross14designprese -cv-engineering_resume 0:c944ee08a5bf -1.06 0.01 layoutlint(java21,javaparser,spo -cv-engineering_resume 0:2d80d05697ad -1.34 0.01 untypedoffsets,implicitpagebreak -cv-engineering_resume 0:6793d28e9783 -1.22 0.01 chromeforge(java,graphcompose,pa -cv-engineering_resume 0:e3cfea265b3b -1.50 0.01 graphcompose:cinematiccovers,pul +cv-engineering_resume 0:32c1cf49a2fe -0.30 0.00 skills +cv-engineering_resume 0:873a24d153c8 -0.12 0.00 languages:java21,kotlin,groovy,p +cv-engineering_resume 0:db84150190bb -0.42 0.00 document&print:pdfbox,apachepoi +cv-engineering_resume 0:69d03fef7130 -0.40 0.00 (docx/xlsx),itext,postscript,icc +cv-engineering_resume 0:d52fd337f016 -0.38 0.00 profiles +cv-engineering_resume 0:f93032b34754 -0.32 0.00 layoutengines:customdsldesign,se +cv-engineering_resume 0:2d6fa255ba3a -0.30 0.00 layouttrees,pagination,snapshott +cv-engineering_resume 0:f274537aaf2c -0.28 0.00 regression +cv-engineering_resume 0:45fcec9fa26d -0.34 0.00 build&infrastructure:maven,gradl +cv-engineering_resume 0:33ddf84f4bab -0.32 0.00 actions,jitpack,docker +cv-engineering_resume 0:af23376e2ec2 -0.26 0.00 testing:junit5,assertj,pdfbox-ba +cv-engineering_resume 0:a8c30cabf363 -0.24 0.00 diff,layout-graphsnapshots,mutat +cv-engineering_resume 0:7c093617a679 -0.22 0.00 (pitest) +cv-engineering_resume 0:11ca7190fe83 -0.25 0.00 distribution:mavencentral,sonaty +cv-engineering_resume 0:768ad260251b -0.23 0.00 gpgsigning,jitpack,semanticversi +cv-engineering_resume 0:d43c8bd5797a -0.21 0.00 discipline +cv-engineering_resume 0:68bf0109c6f8 -0.05 0.00 education +cv-engineering_resume 0:5f9c672fafaf 0.01 0.00 msccomputerscience/2019-2021 +cv-engineering_resume 0:141310eca6fb 0.05 0.00 bscsoftwareengineering/2015-2019 +cv-engineering_resume 0:608c03298f47 -0.03 0.00 oraclejavacertification/2023-202 +cv-engineering_resume 0:41ffd8b76afc -0.13 0.00 details +cv-engineering_resume 0:ecc25e73b19b -0.19 0.00 languages:english(fluent),german +cv-engineering_resume 0:ac7f0ee6a49e -0.17 0.00 (intermediate),spanish(basic) +cv-engineering_resume 0:970ca9d789c2 -0.23 0.00 workeligibility:eligibletoworkin +cv-engineering_resume 0:0735680e2596 -0.21 0.00 theeu +cv-engineering_resume 0:e8256e23459a -0.22 0.05 engineeringprofile +cv-engineering_resume 0:e9b75496bfb4 -0.27 0.05 platformengineerwith10+yearsbuil +cv-engineering_resume 0:866be9f7a132 -0.33 0.05 developer-facingtemplatesystems. +cv-engineering_resume 0:82c1650fbfe8 -0.27 0.05 dsls,andturningbrittleproduction +cv-engineering_resume 0:53e5e7c5a884 -0.28 0.09 experience +cv-engineering_resume 0:4977534824cc -0.14 0.01 seniorplatformengineer/2024-pres +cv-engineering_resume 0:f890faef907f -0.11 0.01 northwindsystems +cv-engineering_resume 0:0bf7eb0b1058 -0.36 0.01 ledthereusabledocument-generatio +cv-engineering_resume 0:d69cae607226 -0.30 0.01 teams.reducedtemplatemaintenance +cv-engineering_resume 0:bdea17333528 -0.24 0.01 engine. +cv-engineering_resume 0:7033b2988e4d -0.13 0.01 softwareengineer/2021-2024 +cv-engineering_resume 0:998c1a985022 -0.10 0.01 brightleaflabs +cv-engineering_resume 0:e77e909f6ff5 -0.35 0.01 builtbackendservicesandproductio +cv-engineering_resume 0:97c59b2fdb55 -0.29 0.01 drovethemigrationfromitexttoacus +cv-engineering_resume 0:2c2b19cf214d -0.23 0.01 latencyfrom1.4sto380ms. +cv-engineering_resume 0:8b5abdc8c0d7 -0.17 0.09 technicalevidence +cv-engineering_resume 0:e2fbf67cb588 0.42 0.01 graphcompose(java21,pdfbox,maven +cv-engineering_resume 0:eb5950729749 0.26 0.01 templates,snapshottesting.powers +cv-engineering_resume 0:81c8132f9792 0.16 0.01 systems.(opensource) +cv-engineering_resume 0:643428f0ebf8 0.76 0.01 templatestudio(kotlin,composedes +cv-engineering_resume 0:c259a0e7581e 0.48 0.01 invoiceoutputacross14designprese +cv-engineering_resume 0:c944ee08a5bf 0.98 0.01 layoutlint(java21,javaparser,spo +cv-engineering_resume 0:2d80d05697ad 0.70 0.01 untypedoffsets,implicitpagebreak +cv-engineering_resume 0:6793d28e9783 1.18 0.01 chromeforge(java,graphcompose,pa +cv-engineering_resume 0:e3cfea265b3b 0.90 0.01 graphcompose:cinematiccovers,pul cv-executive 0:8f1010120ed6 0.08 -0.04 jordanrivera cv-executive 0:89ff05847e96 -0.30 -0.04 london,uk|+442055551000 cv-executive 0:8817bf9310b6 -0.32 -0.04 jordan.rivera@example.com|linked @@ -645,46 +645,46 @@ cv-midnight_navy 0:200b36afcfde -0.07 0.04 hubspotacademy cv-midnight_navy 0:1bea20e1df19 -0.02 0.04 2021 cv-minimal_underlined 0:8f1010120ed6 0.50 0.22 jordanrivera cv-minimal_underlined 0:8d7a2cca3060 0.18 0.07 +442055551000|jordan.rivera@exam -cv-minimal_underlined 0:b944906ed84c -0.09 0.04 professionalsummary -cv-minimal_underlined 0:80cc87fdc4c4 -0.74 0.00 platformengineerwith10+yearsbuil -cv-minimal_underlined 0:bddc0bd093ce -0.57 0.00 systems.specialisedinhigh-throug -cv-minimal_underlined 0:95a43d7b3df0 -0.53 0.00 snapshot-testedlibrariesthatscal -cv-minimal_underlined 0:5f94c50dc5bf -0.30 0.04 technicalskills -cv-minimal_underlined 0:eea537278f83 -0.71 0.00 •languages:java21,kotlin,groovy, -cv-minimal_underlined 0:9c2cd7231a53 -0.71 0.00 •document&print:pdfbox,apachepoi -cv-minimal_underlined 0:7bf8639ec5d3 -0.70 0.00 •layoutengines:customdsldesign,s -cv-minimal_underlined 0:8e66776d28d7 -0.67 0.00 •build&infrastructure:maven,grad -cv-minimal_underlined 0:1ed4fc7d7768 -0.66 0.00 •testing:junit5,assertj,pdfbox-b -cv-minimal_underlined 0:26671c309eb9 -0.66 0.00 •distribution:mavencentral,sonat -cv-minimal_underlined 0:68bf0109c6f8 -0.55 0.04 education -cv-minimal_underlined 0:0ad1957d6bab -0.78 0.00 msccomputerscience -cv-minimal_underlined 0:3fa772117260 -0.85 -0.95 2019-2021 -cv-minimal_underlined 0:47ce0218bbea -0.90 0.00 universityofmanchester -cv-minimal_underlined 0:2ffe115b06e5 -0.84 0.00 distinction.thesis:composablelay -cv-minimal_underlined 0:b6749d0b616b -0.82 0.00 bscsoftwareengineering -cv-minimal_underlined 0:30f9262640a0 -0.88 -0.95 2015-2019 -cv-minimal_underlined 0:89ad9656f393 -0.94 0.00 imperialcollegelondon -cv-minimal_underlined 0:baa173b4a82e -0.86 0.00 first-classhonours.specialisatio -cv-minimal_underlined 0:6d3d5673c39f -0.71 0.00 oraclejavacertification -cv-minimal_underlined 0:d40b22f00acb -0.78 -0.95 2023-2024 -cv-minimal_underlined 0:2669e1f6d55c -0.83 0.00 professionaltrack -cv-minimal_underlined 0:3857373829c1 -0.77 0.00 java17platformdeep-dive:records, -cv-minimal_underlined 0:2577c0f557b2 -0.67 0.04 projects -cv-minimal_underlined 0:b2b029995203 -1.08 0.00 •graphcompose(java21,pdfbox,mave -cv-minimal_underlined 0:67593a76ef70 -1.35 0.02 declarativejavapdflayoutengine.s -cv-minimal_underlined 0:b9292cbd1454 -1.31 0.02 pipelinesforhiringtoolsandbillin -cv-minimal_underlined 0:1b50bb81df5a -1.10 0.00 •templatestudio(kotlin,composede -cv-minimal_underlined 0:7127a108c33c -1.35 0.02 internaltoolforevaluatingcv,prop -cv-minimal_underlined 0:6b844249c695 -1.30 0.02 freezing. -cv-minimal_underlined 0:25cdca2beb8b -0.98 0.00 •layoutlint(java21,javaparser,sp -cv-minimal_underlined 0:7488006d7864 -1.25 0.02 staticanalyserthatflagsfragileau -cv-minimal_underlined 0:c4d0c415b4f8 -1.21 0.02 production. -cv-minimal_underlined 0:fb1927f88597 -1.00 0.00 •chromeforge(java,graphcompose,p -cv-minimal_underlined 0:e7e62230eb1f -0.92 0.02 editorial-magazinedocumenttoolki -cv-minimal_underlined 0:c2f296ef30a3 -0.94 0.04 professionalexperience -cv-minimal_underlined 0:a76f47480818 -1.17 0.00 seniorplatformengineer -cv-minimal_underlined 0:060300b18051 -1.23 -0.01 2024-present -cv-minimal_underlined 0:f890faef907f -1.26 0.00 northwindsystems +cv-minimal_underlined 0:b944906ed84c 0.27 0.04 professionalsummary +cv-minimal_underlined 0:80cc87fdc4c4 -0.02 0.00 platformengineerwith10+yearsbuil +cv-minimal_underlined 0:bddc0bd093ce 0.03 0.00 systems.specialisedinhigh-throug +cv-minimal_underlined 0:95a43d7b3df0 0.07 0.00 snapshot-testedlibrariesthatscal +cv-minimal_underlined 0:5f94c50dc5bf 0.42 0.04 technicalskills +cv-minimal_underlined 0:eea537278f83 0.37 0.00 •languages:java21,kotlin,groovy, +cv-minimal_underlined 0:9c2cd7231a53 0.37 0.00 •document&print:pdfbox,apachepoi +cv-minimal_underlined 0:7bf8639ec5d3 0.38 0.00 •layoutengines:customdsldesign,s +cv-minimal_underlined 0:8e66776d28d7 0.41 0.00 •build&infrastructure:maven,grad +cv-minimal_underlined 0:1ed4fc7d7768 0.42 0.00 •testing:junit5,assertj,pdfbox-b +cv-minimal_underlined 0:26671c309eb9 0.42 0.00 •distribution:mavencentral,sonat +cv-minimal_underlined 0:68bf0109c6f8 0.53 0.04 education +cv-minimal_underlined 0:0ad1957d6bab 0.54 0.00 msccomputerscience +cv-minimal_underlined 0:3fa772117260 0.59 -0.95 2019-2021 +cv-minimal_underlined 0:47ce0218bbea 0.42 0.00 universityofmanchester +cv-minimal_underlined 0:2ffe115b06e5 0.48 0.00 distinction.thesis:composablelay +cv-minimal_underlined 0:b6749d0b616b 0.62 0.00 bscsoftwareengineering +cv-minimal_underlined 0:30f9262640a0 0.56 -0.95 2015-2019 +cv-minimal_underlined 0:89ad9656f393 0.50 0.00 imperialcollegelondon +cv-minimal_underlined 0:baa173b4a82e 0.58 0.00 first-classhonours.specialisatio +cv-minimal_underlined 0:6d3d5673c39f 0.61 0.00 oraclejavacertification +cv-minimal_underlined 0:d40b22f00acb 0.66 -0.95 2023-2024 +cv-minimal_underlined 0:2669e1f6d55c 0.49 0.00 professionaltrack +cv-minimal_underlined 0:3857373829c1 0.67 0.00 java17platformdeep-dive:records, +cv-minimal_underlined 0:2577c0f557b2 0.65 0.04 projects +cv-minimal_underlined 0:b2b029995203 0.60 0.00 •graphcompose(java21,pdfbox,mave +cv-minimal_underlined 0:67593a76ef70 0.45 0.02 declarativejavapdflayoutengine.s +cv-minimal_underlined 0:b9292cbd1454 0.49 0.02 pipelinesforhiringtoolsandbillin +cv-minimal_underlined 0:1b50bb81df5a 0.70 0.00 •templatestudio(kotlin,composede +cv-minimal_underlined 0:7127a108c33c 0.45 0.02 internaltoolforevaluatingcv,prop +cv-minimal_underlined 0:6b844249c695 0.50 0.02 freezing. +cv-minimal_underlined 0:25cdca2beb8b 0.70 0.00 •layoutlint(java21,javaparser,sp +cv-minimal_underlined 0:7488006d7864 0.43 0.02 staticanalyserthatflagsfragileau +cv-minimal_underlined 0:c4d0c415b4f8 0.47 0.02 production. +cv-minimal_underlined 0:fb1927f88597 0.80 0.00 •chromeforge(java,graphcompose,p +cv-minimal_underlined 0:e7e62230eb1f 0.88 0.02 editorial-magazinedocumenttoolki +cv-minimal_underlined 0:c2f296ef30a3 0.86 0.04 professionalexperience +cv-minimal_underlined 0:a76f47480818 0.87 0.00 seniorplatformengineer +cv-minimal_underlined 0:060300b18051 0.81 -0.01 2024-present +cv-minimal_underlined 0:f890faef907f 0.78 0.00 northwindsystems cv-minimal_underlined 1:49faf14f1f56 -0.10 0.00 ledthereusabledocument-generatio cv-minimal_underlined 1:6bd3f168e89e -0.05 0.00 maintenancetimeby70%byretiringpe cv-minimal_underlined 1:daf65306b3b6 0.21 0.00 softwareengineer @@ -698,10 +698,10 @@ cv-minimal_underlined 1:ef148f221e31 0.24 0.00 helixprintco cv-minimal_underlined 1:9d31a6bfbc69 0.06 0.00 maintainedahigh-volumeinvoice-pr cv-minimal_underlined 1:03af8a628309 0.11 0.00 change. cv-minimal_underlined 1:676dfdd56ad2 0.33 0.04 additionalinformation -cv-minimal_underlined 1:f20997652453 -0.08 0.00 languages:english(fluent),german -cv-minimal_underlined 1:ec9d3622395e 0.08 0.00 workeligibility:eligibletoworkin -cv-minimal_underlined 1:dd20ae01c3cf 0.08 0.00 opensource:maintainerofgraphcomp -cv-minimal_underlined 1:33c35e9d236d 0.09 0.00 speaking:jvmsummit2024,devoxxuk2 +cv-minimal_underlined 1:f20997652453 0.28 0.00 languages:english(fluent),german +cv-minimal_underlined 1:ec9d3622395e 0.44 0.00 workeligibility:eligibletoworkin +cv-minimal_underlined 1:dd20ae01c3cf 0.44 0.00 opensource:maintainerofgraphcomp +cv-minimal_underlined 1:33c35e9d236d 0.45 0.00 speaking:jvmsummit2024,devoxxuk2 cv-mint_editorial 0:8f1010120ed6 -0.18 -0.16 jordanrivera cv-mint_editorial 0:2d58f0cadc2d 0.01 -0.68 platformengineer cv-mint_editorial 0:093e7d5fdbaa -0.13 0.00 contact @@ -764,57 +764,57 @@ cv-mint_editorial 1:1081945512b1 0.32 0.07 authoredthecompliancetestharness cv-modern_professional 0:8f1010120ed6 0.18 0.13 jordanrivera cv-modern_professional 0:89ff05847e96 0.12 0.03 london,uk|+442055551000 cv-modern_professional 0:8817bf9310b6 0.07 0.13 jordan.rivera@example.com|linked -cv-modern_professional 0:b944906ed84c 0.02 0.00 professionalsummary -cv-modern_professional 0:6fbdc8b79878 -0.49 0.00 platformengineerwith10+yearsbuil -cv-modern_professional 0:5f94c50dc5bf -0.01 0.00 technicalskills -cv-modern_professional 0:eea537278f83 -0.15 0.00 •languages:java21,kotlin,groovy, -cv-modern_professional 0:9c2cd7231a53 0.00 0.00 •document&print:pdfbox,apachepoi -cv-modern_professional 0:7bf8639ec5d3 -0.09 0.00 •layoutengines:customdsldesign,s -cv-modern_professional 0:8e66776d28d7 -0.06 0.00 •build&infrastructure:maven,grad -cv-modern_professional 0:1ed4fc7d7768 -0.03 0.00 •testing:junit5,assertj,pdfbox-b -cv-modern_professional 0:26671c309eb9 0.00 0.00 •distribution:mavencentral,sonat -cv-modern_professional 0:68bf0109c6f8 0.11 0.00 education -cv-modern_professional 0:0ad1957d6bab -0.07 0.00 msccomputerscience -cv-modern_professional 0:3fa772117260 -0.08 0.07 2019-2021 -cv-modern_professional 0:3fa772117260#1 0.05 0.07 2019-2021 -cv-modern_professional 0:47ce0218bbea -0.19 0.00 universityofmanchester -cv-modern_professional 0:2ffe115b06e5 -0.06 0.00 distinction.thesis:composablelay -cv-modern_professional 0:b6749d0b616b -0.04 0.00 bscsoftwareengineering -cv-modern_professional 0:30f9262640a0 -0.05 0.07 2015-2019 -cv-modern_professional 0:89ad9656f393 -0.16 0.00 imperialcollegelondon -cv-modern_professional 0:baa173b4a82e -0.03 0.00 first-classhonours.specialisatio -cv-modern_professional 0:6d3d5673c39f -0.01 0.00 oraclejavacertification -cv-modern_professional 0:d40b22f00acb -0.02 0.07 2023-2024 -cv-modern_professional 0:2669e1f6d55c -0.13 0.00 professionaltrack -cv-modern_professional 0:3857373829c1 0.00 0.00 java17platformdeep-dive:records, -cv-modern_professional 0:2577c0f557b2 0.10 0.00 projects -cv-modern_professional 0:b2b029995203 -0.04 0.00 •graphcompose(java21,pdfbox,mave -cv-modern_professional 0:dd39d2ff3520 -0.41 0.00 declarativejavapdflayoutengine.s -cv-modern_professional 0:9ecaa6df6d41 -0.21 0.00 invoice/proposalpipelinesforhiri -cv-modern_professional 0:1b50bb81df5a -0.04 0.00 •templatestudio(kotlin,composede -cv-modern_professional 0:18eec9e76e2d -0.41 0.00 internaltoolforevaluatingcv,prop -cv-modern_professional 0:6bc2807453c6 -0.21 0.00 baselinefreezing. -cv-modern_professional 0:25cdca2beb8b -0.04 0.00 •layoutlint(java21,javaparser,sp -cv-modern_professional 0:cc2850ddd8ba -0.41 0.00 staticanalyserthatflagsfragileau -cv-modern_professional 0:7b985a1d2b08 -0.21 0.00 shiptoproduction. -cv-modern_professional 0:fb1927f88597 -0.04 0.00 •chromeforge(java,graphcompose,p -cv-modern_professional 0:cda7db6c6ea6 -0.41 0.00 editorial-magazinedocumenttoolki -cv-modern_professional 0:fe63fe18585a -0.21 0.00 callouts. -cv-modern_professional 0:c2f296ef30a3 0.14 0.00 professionalexperience -cv-modern_professional 0:a76f47480818 0.08 0.00 seniorplatformengineer -cv-modern_professional 0:060300b18051 0.08 0.17 2024-present -cv-modern_professional 0:f890faef907f -0.04 0.00 northwindsystems -cv-modern_professional 0:a6525dacbac7 -0.27 0.00 ledthereusabledocument-generatio -cv-modern_professional 0:15e3905f4890 -0.19 0.00 reducedtemplatemaintenancetimeby -cv-modern_professional 0:daf65306b3b6 0.07 0.00 softwareengineer -cv-modern_professional 0:e7cc1822c6dc 0.07 0.07 2021-2024 -cv-modern_professional 0:998c1a985022 -0.05 0.00 brightleaflabs -cv-modern_professional 0:e86691b0219f -0.27 0.00 builtbackendservicesandproductio -cv-modern_professional 0:4ec57434564a -0.20 0.00 migrationfromitexttoacustomlayou -cv-modern_professional 0:41bb54fbae8d 0.05 0.00 backendengineer -cv-modern_professional 0:ef148f221e31 -0.06 0.00 helixprintco -cv-modern_professional 0:a32c7f2401d9 -0.29 0.00 maintainedahigh-volumeinvoice-pr -cv-modern_professional 0:7068c1d7034b -0.18 0.00 everytemplatechange. +cv-modern_professional 0:b944906ed84c 0.38 0.00 professionalsummary +cv-modern_professional 0:6fbdc8b79878 -0.12 0.00 platformengineerwith10+yearsbuil +cv-modern_professional 0:5f94c50dc5bf 0.47 0.00 technicalskills +cv-modern_professional 0:eea537278f83 0.33 0.00 •languages:java21,kotlin,groovy, +cv-modern_professional 0:9c2cd7231a53 0.36 0.00 •document&print:pdfbox,apachepoi +cv-modern_professional 0:7bf8639ec5d3 0.39 0.00 •layoutengines:customdsldesign,s +cv-modern_professional 0:8e66776d28d7 0.30 0.00 •build&infrastructure:maven,grad +cv-modern_professional 0:1ed4fc7d7768 0.33 0.00 •testing:junit5,assertj,pdfbox-b +cv-modern_professional 0:26671c309eb9 0.36 0.00 •distribution:mavencentral,sonat +cv-modern_professional 0:68bf0109c6f8 0.47 0.00 education +cv-modern_professional 0:0ad1957d6bab 0.41 0.00 msccomputerscience +cv-modern_professional 0:3fa772117260 0.40 0.07 2019-2021 +cv-modern_professional 0:3fa772117260#1 0.41 0.07 2019-2021 +cv-modern_professional 0:47ce0218bbea 0.29 0.00 universityofmanchester +cv-modern_professional 0:2ffe115b06e5 0.42 0.00 distinction.thesis:composablelay +cv-modern_professional 0:b6749d0b616b 0.32 0.00 bscsoftwareengineering +cv-modern_professional 0:30f9262640a0 0.43 0.07 2015-2019 +cv-modern_professional 0:89ad9656f393 0.20 0.00 imperialcollegelondon +cv-modern_professional 0:baa173b4a82e 0.33 0.00 first-classhonours.specialisatio +cv-modern_professional 0:6d3d5673c39f 0.35 0.00 oraclejavacertification +cv-modern_professional 0:d40b22f00acb 0.35 0.07 2023-2024 +cv-modern_professional 0:2669e1f6d55c 0.23 0.00 professionaltrack +cv-modern_professional 0:3857373829c1 0.36 0.00 java17platformdeep-dive:records, +cv-modern_professional 0:2577c0f557b2 0.46 0.00 projects +cv-modern_professional 0:b2b029995203 0.32 0.00 •graphcompose(java21,pdfbox,mave +cv-modern_professional 0:dd39d2ff3520 0.07 0.00 declarativejavapdflayoutengine.s +cv-modern_professional 0:9ecaa6df6d41 0.15 0.00 invoice/proposalpipelinesforhiri +cv-modern_professional 0:1b50bb81df5a 0.44 0.00 •templatestudio(kotlin,composede +cv-modern_professional 0:18eec9e76e2d 0.07 0.00 internaltoolforevaluatingcv,prop +cv-modern_professional 0:6bc2807453c6 0.15 0.00 baselinefreezing. +cv-modern_professional 0:25cdca2beb8b 0.44 0.00 •layoutlint(java21,javaparser,sp +cv-modern_professional 0:cc2850ddd8ba 0.07 0.00 staticanalyserthatflagsfragileau +cv-modern_professional 0:7b985a1d2b08 0.15 0.00 shiptoproduction. +cv-modern_professional 0:fb1927f88597 0.44 0.00 •chromeforge(java,graphcompose,p +cv-modern_professional 0:cda7db6c6ea6 0.07 0.00 editorial-magazinedocumenttoolki +cv-modern_professional 0:fe63fe18585a 0.15 0.00 callouts. +cv-modern_professional 0:c2f296ef30a3 0.50 0.00 professionalexperience +cv-modern_professional 0:a76f47480818 0.44 0.00 seniorplatformengineer +cv-modern_professional 0:060300b18051 0.43 0.17 2024-present +cv-modern_professional 0:f890faef907f 0.32 0.00 northwindsystems +cv-modern_professional 0:a6525dacbac7 0.09 0.00 ledthereusabledocument-generatio +cv-modern_professional 0:15e3905f4890 0.17 0.00 reducedtemplatemaintenancetimeby +cv-modern_professional 0:daf65306b3b6 0.43 0.00 softwareengineer +cv-modern_professional 0:e7cc1822c6dc 0.42 0.07 2021-2024 +cv-modern_professional 0:998c1a985022 0.31 0.00 brightleaflabs +cv-modern_professional 0:e86691b0219f 0.09 0.00 builtbackendservicesandproductio +cv-modern_professional 0:4ec57434564a 0.16 0.00 migrationfromitexttoacustomlayou +cv-modern_professional 0:41bb54fbae8d 0.41 0.00 backendengineer +cv-modern_professional 0:ef148f221e31 0.30 0.00 helixprintco +cv-modern_professional 0:a32c7f2401d9 0.07 0.00 maintainedahigh-volumeinvoice-pr +cv-modern_professional 0:7068c1d7034b 0.17 0.00 everytemplatechange. cv-modern_professional 1:676dfdd56ad2 0.39 0.00 additionalinformation cv-modern_professional 1:f20997652453 0.24 0.00 languages:english(fluent),german cv-modern_professional 1:ec9d3622395e 0.27 0.00 workeligibility:eligibletoworkin @@ -949,32 +949,32 @@ cv-nordic_clean 0:c0b0109d9439 -0.10 -0.21 github cv-nordic_clean 0:1900eab6c028 -0.14 -0.04 profile cv-nordic_clean 0:8d6758a29c08 -0.45 -0.04 platformengineerwith10+yearsbuil cv-nordic_clean 0:f0d993eb5f9d -0.44 -0.04 high-throughputpdfrendering,sema -cv-nordic_clean 0:32c1cf49a2fe 0.01 0.08 skills -cv-nordic_clean 0:873a24d153c8 0.09 0.08 languages:java21,kotlin,groovy,p -cv-nordic_clean 0:db84150190bb -0.15 0.08 document&print:pdfbox,apachepoi -cv-nordic_clean 0:1d1d129512e6 -0.06 0.08 (docx/xlsx),itext,postscript,icc -cv-nordic_clean 0:7985eee03934 -0.09 0.08 fontmetrics -cv-nordic_clean 0:a1cec3782701 -0.09 0.08 layoutengines:customdsldesign,se -cv-nordic_clean 0:3a3b8c3bddd0 0.00 0.08 trees,pagination,snapshottesting -cv-nordic_clean 0:b7d8ca9428a4 0.00 0.08 build&infrastructure:maven,gradl -cv-nordic_clean 0:656a2a3e57e0 -0.03 0.08 jitpack,docker,jmhbenchmarking -cv-nordic_clean 0:b8b1a42a45e1 0.09 0.08 testing:junit5,assertj,pdfbox-ba -cv-nordic_clean 0:2ec2836b6df6 0.09 0.08 layout-graphsnapshots,mutationte -cv-nordic_clean 0:74b69eb8de4b 0.09 0.08 distribution:mavencentral,sonaty -cv-nordic_clean 0:43ad67a4e3f5 0.06 0.08 signing,jitpack,semanticversioni -cv-nordic_clean 0:68bf0109c6f8 0.28 0.08 education -cv-nordic_clean 0:904a600c3869 0.10 0.08 msccomputerscience/universityofm -cv-nordic_clean 0:3fa772117260 0.27 0.08 2019-2021 -cv-nordic_clean 0:78a380e4d1f0 0.29 0.08 bscsoftwareengineering/imperialc -cv-nordic_clean 0:30f9262640a0 0.46 0.08 2015-2019 -cv-nordic_clean 0:7b476727faf3 0.91 0.08 additional -cv-nordic_clean 0:3b0f5db9217f 0.80 0.08 languages:english(fluent),german -cv-nordic_clean 0:d8a971cea795 0.71 0.08 spanish(basic) -cv-nordic_clean 0:ec9d3622395e 0.91 0.08 workeligibility:eligibletoworkin -cv-nordic_clean 0:d05b8b335e96 0.61 0.08 opensource:maintainerofgraphcomp -cv-nordic_clean 0:2f3b4176123d 0.64 0.08 contributortopdfboxissuetriage. -cv-nordic_clean 0:b6b5a250cb72 0.58 0.08 speaking:jvmsummit2024,devoxxuk2 -cv-nordic_clean 0:7ead14c50085 0.73 0.08 ondeclarativedocumentlayout. +cv-nordic_clean 0:32c1cf49a2fe -0.23 0.08 skills +cv-nordic_clean 0:873a24d153c8 -0.03 0.08 languages:java21,kotlin,groovy,p +cv-nordic_clean 0:db84150190bb -0.27 0.08 document&print:pdfbox,apachepoi +cv-nordic_clean 0:1d1d129512e6 -0.30 0.08 (docx/xlsx),itext,postscript,icc +cv-nordic_clean 0:7985eee03934 -0.33 0.08 fontmetrics +cv-nordic_clean 0:a1cec3782701 -0.21 0.08 layoutengines:customdsldesign,se +cv-nordic_clean 0:3a3b8c3bddd0 -0.24 0.08 trees,pagination,snapshottesting +cv-nordic_clean 0:b7d8ca9428a4 -0.24 0.08 build&infrastructure:maven,gradl +cv-nordic_clean 0:656a2a3e57e0 -0.15 0.08 jitpack,docker,jmhbenchmarking +cv-nordic_clean 0:b8b1a42a45e1 -0.15 0.08 testing:junit5,assertj,pdfbox-ba +cv-nordic_clean 0:2ec2836b6df6 -0.15 0.08 layout-graphsnapshots,mutationte +cv-nordic_clean 0:74b69eb8de4b -0.03 0.08 distribution:mavencentral,sonaty +cv-nordic_clean 0:43ad67a4e3f5 -0.06 0.08 signing,jitpack,semanticversioni +cv-nordic_clean 0:68bf0109c6f8 0.04 0.08 education +cv-nordic_clean 0:904a600c3869 -0.14 0.08 msccomputerscience/universityofm +cv-nordic_clean 0:3fa772117260 0.03 0.08 2019-2021 +cv-nordic_clean 0:78a380e4d1f0 0.17 0.08 bscsoftwareengineering/imperialc +cv-nordic_clean 0:30f9262640a0 0.34 0.08 2015-2019 +cv-nordic_clean 0:7b476727faf3 0.67 0.08 additional +cv-nordic_clean 0:3b0f5db9217f 0.56 0.08 languages:english(fluent),german +cv-nordic_clean 0:d8a971cea795 0.47 0.08 spanish(basic) +cv-nordic_clean 0:ec9d3622395e 0.67 0.08 workeligibility:eligibletoworkin +cv-nordic_clean 0:d05b8b335e96 0.49 0.08 opensource:maintainerofgraphcomp +cv-nordic_clean 0:2f3b4176123d 0.52 0.08 contributortopdfboxissuetriage. +cv-nordic_clean 0:b6b5a250cb72 0.46 0.08 speaking:jvmsummit2024,devoxxuk2 +cv-nordic_clean 0:7ead14c50085 0.49 0.08 ondeclarativedocumentlayout. cv-nordic_clean 0:53e5e7c5a884 -0.23 0.07 experience cv-nordic_clean 0:4977534824cc -0.15 0.07 seniorplatformengineer/2024-pres cv-nordic_clean 0:f890faef907f -0.08 0.07 northwindsystems @@ -1103,80 +1103,80 @@ cv-orange_ops 0:0945b35c95a8 0.90 -0.02 systems:sapewm,manhattanwms,micr cv-orange_ops 0:44aaa523dc2c 0.92 -0.02 languages:english(native) cv-orange_ops 0:724cc536a24c 0.96 -0.02 drivinglicence:fullukdrivinglice cv-orange_ops 0:9f0e43069d3f 0.98 -0.02 interests:strengthtraining,motor -cv-panel 0:8f1010120ed6 0.42 0.25 jordanrivera -cv-panel 0:2d58f0cadc2d 0.20 -0.05 platformengineer -cv-panel 0:89ff05847e96 0.20 0.30 london,uk|+442055551000 -cv-panel 0:8817bf9310b6 0.16 0.36 jordan.rivera@example.com|linked -cv-panel 0:1900eab6c028 0.50 0.04 profile -cv-panel 0:80cc87fdc4c4 -0.26 0.04 platformengineerwith10+yearsbuil -cv-panel 0:c323ef4c385f -0.26 0.04 systems.specialisedinhigh-throug -cv-panel 0:3ff1933dba9a -0.26 0.04 typed,snapshot-testedlibrariesth -cv-panel 0:32c1cf49a2fe 0.82 0.04 skills -cv-panel 0:eea537278f83 0.30 0.04 •languages:java21,kotlin,groovy, -cv-panel 0:7e941e729572 0.17 0.04 •document&print:pdfbox,apachepoi -cv-panel 0:9e3166ce2413 0.17 0.04 itext,postscript,icccolourprofil -cv-panel 0:ebc70ed9b71b 0.13 0.04 •layoutengines:customdsldesign,s -cv-panel 0:dd4f24d85605 0.13 0.04 pagination,snapshottesting,visua -cv-panel 0:f5f76d479ec8 0.21 0.04 •build&infrastructure:maven,grad -cv-panel 0:656a2a3e57e0 0.21 0.04 jitpack,docker,jmhbenchmarking -cv-panel 0:9a6921f79b7d 0.25 0.04 •distribution:mavencentral,sonat -cv-panel 0:77a74982066f 0.25 0.04 jitpack,semanticversioningdiscip -cv-panel 0:68bf0109c6f8 0.85 0.04 education -cv-panel 0:871923f4f0f2 0.39 0.04 msccomputerscience-2019-2021 -cv-panel 0:47ce0218bbea 0.43 0.04 universityofmanchester -cv-panel 0:51e1ec7daa5a 0.11 0.04 distinction.thesis:composablelay -cv-panel 0:d10553cd7368 0.11 0.04 deterministicdocumentrendering. -cv-panel 0:ba6d361079f4 0.39 0.04 bscsoftwareengineering-2015-2019 -cv-panel 0:89ad9656f393 0.43 0.04 imperialcollegelondon -cv-panel 0:4c58bcad7242 0.23 0.04 first-classhonours.specialisatio -cv-panel 0:2189b9b3b549 0.23 0.04 analysis. -cv-panel 0:8971b01c36bb 0.51 0.04 oraclejavacertification-2023-202 -cv-panel 0:2669e1f6d55c 0.55 0.04 professionaltrack -cv-panel 0:4f17e3d7d6f4 0.23 0.04 java17platformdeep-dive:records, -cv-panel 0:9e6154a3b625 0.23 0.04 matching,virtualthreads. -cv-panel 0:7b476727faf3 0.86 0.04 additional -cv-panel 0:3f88eb4c530c 0.10 0.04 languages:english(fluent),german -cv-panel 0:5d276fee8c17 0.10 0.04 (basic) -cv-panel 0:ec9d3622395e 0.42 0.04 workeligibility:eligibletoworkin -cv-panel 0:d05b8b335e96 0.14 0.04 opensource:maintainerofgraphcomp -cv-panel 0:2f3b4176123d 0.14 0.04 contributortopdfboxissuetriage. -cv-panel 0:1ae173b42166 0.22 0.04 speaking:jvmsummit2024,devoxxuk2 -cv-panel 0:309255ca6a36 0.22 0.04 declarativedocumentlayout. -cv-panel 0:53e5e7c5a884 0.82 0.05 experience -cv-panel 0:99b44abc1b3e 0.34 0.05 seniorplatformengineer-2024-pres -cv-panel 0:f890faef907f 0.41 0.05 northwindsystems -cv-panel 0:e32ca827bfd5 0.09 0.05 ledthereusabledocument-generatio -cv-panel 0:675f8862fdda 0.09 0.05 hiring,andreportingflowsacross8p -cv-panel 0:93d48fc85054 0.09 0.05 templatemaintenancetimeby70%byre -cv-panel 0:e7f09e2ba7d2 0.21 0.05 scriptsinfavourofonecanonicaleng -cv-panel 0:ded138c59d03 0.49 0.05 softwareengineer-2021-2024 -cv-panel 0:998c1a985022 0.53 0.05 brightleaflabs -cv-panel 0:0ed66ac9265d 0.21 0.05 builtbackendservicesandproductio -cv-panel 0:17c4ef49d4e6 0.21 0.05 pipelinesprocessing2m+documentsp -cv-panel 0:a7dd3c5be76b 0.21 0.05 migrationfromitexttoacustomlayou -cv-panel 0:a35401d8bcad 0.21 0.05 licensingriskandcuttingp99render -cv-panel 0:649d2d9d10d0 0.33 0.05 380ms. -cv-panel 0:019bbdc8d0bb 0.61 0.05 backendengineer-2019-2021 -cv-panel 0:ef148f221e31 0.67 0.05 helixprintco -cv-panel 0:09cc06a649eb 0.35 0.05 maintainedahigh-volumeinvoice-pr -cv-panel 0:090e2184c17b 0.35 0.05 pdfs/year)andauthoredthecomplian -cv-panel 0:6f071fdf7529 0.35 0.05 gatedeverytemplatechange. -cv-panel 0:2577c0f557b2 0.95 0.05 projects -cv-panel 0:b2b029995203 0.43 0.05 •graphcompose(java21,pdfbox,mave -cv-panel 0:81c8132f9792 0.31 0.07 systems.(opensource) -cv-panel 0:753f46e4e01b 0.34 0.05 •templatestudio(kotlin,composede -cv-panel 0:6eb35b5b9a91 0.34 0.07 diff) -cv-panel 0:d919bd2d50b6 0.34 0.07 internaltoolforevaluatingcv,prop -cv-panel 0:245b9e56b9de 0.34 0.07 across14designpresets.pngdiffing -cv-panel 0:6bc2807453c6 0.46 0.07 baselinefreezing. -cv-panel 0:25cdca2beb8b 0.70 0.05 •layoutlint(java21,javaparser,sp -cv-panel 0:30e034b9c7b2 0.46 0.07 staticanalyserthatflagsfragileau -cv-panel 0:e7ad19d64668 0.46 0.07 nestedrows,untypedoffsets,implic -cv-panel 0:95ac1a62c76f 0.46 0.07 theyshiptoproduction. -cv-panel 0:fb1927f88597 0.70 0.05 •chromeforge(java,graphcompose,p -cv-panel 0:bb865a4ccac1 0.58 0.07 editorial-magazinedocumenttoolki -cv-panel 0:8a31ccd889ee 0.58 0.07 cinematiccovers,pullquotes,multi -cv-panel 0:fe63fe18585a 0.58 0.07 callouts. +cv-panel 0:8f1010120ed6 0.18 0.25 jordanrivera +cv-panel 0:2d58f0cadc2d -0.16 -0.05 platformengineer +cv-panel 0:89ff05847e96 -0.16 0.30 london,uk|+442055551000 +cv-panel 0:8817bf9310b6 -0.08 0.36 jordan.rivera@example.com|linked +cv-panel 0:1900eab6c028 0.74 0.04 profile +cv-panel 0:80cc87fdc4c4 -0.02 0.04 platformengineerwith10+yearsbuil +cv-panel 0:c323ef4c385f -0.02 0.04 systems.specialisedinhigh-throug +cv-panel 0:3ff1933dba9a -0.02 0.04 typed,snapshot-testedlibrariesth +cv-panel 0:32c1cf49a2fe 1.06 0.04 skills +cv-panel 0:eea537278f83 0.54 0.04 •languages:java21,kotlin,groovy, +cv-panel 0:7e941e729572 0.29 0.04 •document&print:pdfbox,apachepoi +cv-panel 0:9e3166ce2413 0.29 0.04 itext,postscript,icccolourprofil +cv-panel 0:ebc70ed9b71b 0.37 0.04 •layoutengines:customdsldesign,s +cv-panel 0:dd4f24d85605 0.37 0.04 pagination,snapshottesting,visua +cv-panel 0:f5f76d479ec8 0.45 0.04 •build&infrastructure:maven,grad +cv-panel 0:656a2a3e57e0 0.45 0.04 jitpack,docker,jmhbenchmarking +cv-panel 0:9a6921f79b7d 0.49 0.04 •distribution:mavencentral,sonat +cv-panel 0:77a74982066f 0.49 0.04 jitpack,semanticversioningdiscip +cv-panel 0:68bf0109c6f8 1.57 0.04 education +cv-panel 0:871923f4f0f2 0.99 0.04 msccomputerscience-2019-2021 +cv-panel 0:47ce0218bbea 1.03 0.04 universityofmanchester +cv-panel 0:51e1ec7daa5a 0.83 0.04 distinction.thesis:composablelay +cv-panel 0:d10553cd7368 0.83 0.04 deterministicdocumentrendering. +cv-panel 0:ba6d361079f4 1.11 0.04 bscsoftwareengineering-2015-2019 +cv-panel 0:89ad9656f393 1.15 0.04 imperialcollegelondon +cv-panel 0:4c58bcad7242 0.83 0.04 first-classhonours.specialisatio +cv-panel 0:2189b9b3b549 0.83 0.04 analysis. +cv-panel 0:8971b01c36bb 1.11 0.04 oraclejavacertification-2023-202 +cv-panel 0:2669e1f6d55c 1.15 0.04 professionaltrack +cv-panel 0:4f17e3d7d6f4 0.95 0.04 java17platformdeep-dive:records, +cv-panel 0:9e6154a3b625 0.95 0.04 matching,virtualthreads. +cv-panel 0:7b476727faf3 1.94 0.04 additional +cv-panel 0:3f88eb4c530c 1.18 0.04 languages:english(fluent),german +cv-panel 0:5d276fee8c17 1.18 0.04 (basic) +cv-panel 0:ec9d3622395e 1.50 0.04 workeligibility:eligibletoworkin +cv-panel 0:d05b8b335e96 1.34 0.04 opensource:maintainerofgraphcomp +cv-panel 0:2f3b4176123d 1.34 0.04 contributortopdfboxissuetriage. +cv-panel 0:1ae173b42166 1.30 0.04 speaking:jvmsummit2024,devoxxuk2 +cv-panel 0:309255ca6a36 1.30 0.04 declarativedocumentlayout. +cv-panel 0:53e5e7c5a884 1.06 0.05 experience +cv-panel 0:99b44abc1b3e 0.46 0.05 seniorplatformengineer-2024-pres +cv-panel 0:f890faef907f 0.53 0.05 northwindsystems +cv-panel 0:e32ca827bfd5 0.33 0.05 ledthereusabledocument-generatio +cv-panel 0:675f8862fdda 0.33 0.05 hiring,andreportingflowsacross8p +cv-panel 0:93d48fc85054 0.33 0.05 templatemaintenancetimeby70%byre +cv-panel 0:e7f09e2ba7d2 0.33 0.05 scriptsinfavourofonecanonicaleng +cv-panel 0:ded138c59d03 0.61 0.05 softwareengineer-2021-2024 +cv-panel 0:998c1a985022 0.65 0.05 brightleaflabs +cv-panel 0:0ed66ac9265d 0.45 0.05 builtbackendservicesandproductio +cv-panel 0:17c4ef49d4e6 0.45 0.05 pipelinesprocessing2m+documentsp +cv-panel 0:a7dd3c5be76b 0.45 0.05 migrationfromitexttoacustomlayou +cv-panel 0:a35401d8bcad 0.45 0.05 licensingriskandcuttingp99render +cv-panel 0:649d2d9d10d0 0.45 0.05 380ms. +cv-panel 0:019bbdc8d0bb 0.73 0.05 backendengineer-2019-2021 +cv-panel 0:ef148f221e31 0.79 0.05 helixprintco +cv-panel 0:09cc06a649eb 0.59 0.05 maintainedahigh-volumeinvoice-pr +cv-panel 0:090e2184c17b 0.59 0.05 pdfs/year)andauthoredthecomplian +cv-panel 0:6f071fdf7529 0.59 0.05 gatedeverytemplatechange. +cv-panel 0:2577c0f557b2 1.67 0.05 projects +cv-panel 0:b2b029995203 1.15 0.05 •graphcompose(java21,pdfbox,mave +cv-panel 0:81c8132f9792 0.91 0.07 systems.(opensource) +cv-panel 0:753f46e4e01b 0.94 0.05 •templatestudio(kotlin,composede +cv-panel 0:6eb35b5b9a91 0.94 0.07 diff) +cv-panel 0:d919bd2d50b6 1.06 0.07 internaltoolforevaluatingcv,prop +cv-panel 0:245b9e56b9de 1.06 0.07 across14designpresets.pngdiffing +cv-panel 0:6bc2807453c6 1.06 0.07 baselinefreezing. +cv-panel 0:25cdca2beb8b 1.30 0.05 •layoutlint(java21,javaparser,sp +cv-panel 0:30e034b9c7b2 1.06 0.07 staticanalyserthatflagsfragileau +cv-panel 0:e7ad19d64668 1.06 0.07 nestedrows,untypedoffsets,implic +cv-panel 0:95ac1a62c76f 1.18 0.07 theyshiptoproduction. +cv-panel 0:fb1927f88597 1.42 0.05 •chromeforge(java,graphcompose,p +cv-panel 0:bb865a4ccac1 1.18 0.07 editorial-magazinedocumenttoolki +cv-panel 0:8a31ccd889ee 1.18 0.07 cinematiccovers,pullquotes,multi +cv-panel 0:fe63fe18585a 1.18 0.07 callouts. cv-professional_sidebar 0:093e7d5fdbaa -0.17 -0.04 contact cv-professional_sidebar 0:7f459725e1f6 0.05 -0.15 +12345678900 cv-professional_sidebar 0:52bf11c1afe0 -0.07 -0.19 your.email@example.com @@ -1274,15 +1274,15 @@ cv-serif_headline 0:2198cdea3aba 0.50 0.00 devsphere|newyork,ny cv-serif_headline 0:173ed9f7b6b1 0.55 0.00 •assistedindevelopingandmaintain cv-serif_headline 0:0a1fbe0c94d9 0.52 0.00 •wroteunitandintegrationteststoe cv-serif_headline 0:bd5eec545fa8 0.50 0.00 •participatedinagileceremoniesan -cv-serif_headline 0:2577c0f557b2 0.65 -0.02 projects -cv-serif_headline 0:c03ade0f8985 0.67 0.01 e-commerceplatform -cv-serif_headline 0:f726495cb8e6 0.64 0.01 java,springboot,react,postgresql -cv-serif_headline 0:09271909c2c5 0.40 0.01 developedafull-stacke-commerce +cv-serif_headline 0:2577c0f557b2 0.53 -0.02 projects +cv-serif_headline 0:c03ade0f8985 0.55 0.01 e-commerceplatform +cv-serif_headline 0:f726495cb8e6 0.52 0.01 java,springboot,react,postgresql +cv-serif_headline 0:09271909c2c5 0.28 0.01 developedafull-stacke-commerce cv-serif_headline 0:a395647dca6c 0.40 0.01 platformwithuserauthentication,p cv-serif_headline 0:19ed6c29c718 0.43 0.01 catalog,cart,andpaymentintegrati -cv-serif_headline 0:1c1e5cfc5031 0.67 0.05 taskmanagementapi -cv-serif_headline 0:4e8f2a166cfe 0.64 0.05 java,springboot,mongodb,docker -cv-serif_headline 0:793437bcb507 0.40 0.05 builtarestfulapifortaskmanagemen +cv-serif_headline 0:1c1e5cfc5031 0.55 0.05 taskmanagementapi +cv-serif_headline 0:4e8f2a166cfe 0.52 0.05 java,springboot,mongodb,docker +cv-serif_headline 0:793437bcb507 0.28 0.05 builtarestfulapifortaskmanagemen cv-serif_headline 0:47492456be77 0.40 0.05 withrole-basedaccess,real-time cv-serif_headline 0:7d9a1a98ac6c 0.43 0.05 updates,anddockerizeddeployment. cv-serif_headline 0:68bf0109c6f8 0.11 0.17 education @@ -1682,6 +1682,7 @@ cv-timeline_minimal 0:54b7bb3a12a0 -0.39 -0.04 jmh):declarativejavapdflayouteng cv-timeline_minimal 0:83ee0a75c2d4 -0.31 -0.04 semanticdsl,slot-basedtemplates, cv-timeline_minimal 0:235802baf524 -0.35 -0.04 snapshottesting.powersproduction cv-timeline_minimal 0:44925c9e42ee -0.39 -0.04 invoice/proposalpipelinesforhiri +cv-timeline_minimal 0:de1af4623873 -0.28 -0.04 andbillingsystems.(opensource) cv-timeline_minimal 0:ae7902eee4b2 -0.40 -0.04 templatestudio(kotlin,composedes cv-timeline_minimal 0:f15436034237 -0.32 -0.04 pdfboxpngdiff):internaltoolfor cv-timeline_minimal 0:24a195694090 -0.36 -0.04 evaluatingcv,proposal,andinvoice @@ -1758,49 +1759,49 @@ cv-violet_grid 0:caf9f906b16a -0.28 -0.44 documentation cv-violet_grid 0:f9d35d43770d -0.16 -0.02 tools cv-violet_grid 0:5cb2b3b6143c -0.09 -0.02 figmafigjamadobexdsketchmironoti cv-violet_grid 0:53e5e7c5a884 -0.05 -0.02 experience -cv-violet_grid 0:5a0774260e0c 0.00 -0.02 2022-present -cv-violet_grid 0:204f460767ff -0.05 -0.05 seniorux/uidesigner|novafin(fint +cv-violet_grid 0:5a0774260e0c -0.12 -0.02 2022-present +cv-violet_grid 0:204f460767ff -0.17 -0.05 seniorux/uidesigner|novafin(fint cv-violet_grid 0:318bba211bdc 0.00 -0.06 sanfrancisco,ca -cv-violet_grid 0:318bba211bdc#1 -0.04 -0.06 sanfrancisco,ca -cv-violet_grid 0:3883e88c63c3 0.03 0.05 ledend-to-enddesignforapersonalf -cv-violet_grid 0:ccc00663f089 -0.02 0.05 conducteduserresearch,builtperso -cv-violet_grid 0:7d0f908c7e5f -0.07 0.05 designedwireframes,prototypes,an -cv-violet_grid 0:9b57c4a85aad 0.01 0.05 establishedandmaintainedascalabl -cv-violet_grid 0:6894eafb99c2 -0.02 0.05 collaboratedwithproductmanagers, -cv-violet_grid 0:01e4455cec51 -0.04 -0.02 2020-2022 -cv-violet_grid 0:24d722f0cfbe -0.09 -0.05 uxdesigner|brighthealth(healthte -cv-violet_grid 0:530707fb0897 -0.01 0.05 redesignedpatientportalexperienc -cv-violet_grid 0:b2e27a1d9270 -0.06 0.05 plannedandfacilitatedusabilityte -cv-violet_grid 0:ab80a52d70fe -0.11 0.05 partneredwithengineerstoensurefe +cv-violet_grid 0:318bba211bdc#1 -0.16 -0.06 sanfrancisco,ca +cv-violet_grid 0:3883e88c63c3 -0.09 0.05 ledend-to-enddesignforapersonalf +cv-violet_grid 0:ccc00663f089 -0.14 0.05 conducteduserresearch,builtperso +cv-violet_grid 0:7d0f908c7e5f -0.19 0.05 designedwireframes,prototypes,an +cv-violet_grid 0:9b57c4a85aad -0.11 0.05 establishedandmaintainedascalabl +cv-violet_grid 0:6894eafb99c2 -0.14 0.05 collaboratedwithproductmanagers, +cv-violet_grid 0:01e4455cec51 -0.16 -0.02 2020-2022 +cv-violet_grid 0:24d722f0cfbe -0.21 -0.05 uxdesigner|brighthealth(healthte +cv-violet_grid 0:530707fb0897 -0.13 0.05 redesignedpatientportalexperienc +cv-violet_grid 0:b2e27a1d9270 -0.18 0.05 plannedandfacilitatedusabilityte +cv-violet_grid 0:ab80a52d70fe -0.23 0.05 partneredwithengineerstoensurefe cv-violet_grid 0:11cbf615189b -0.15 0.05 createdreusablecomponentsandstyl -cv-violet_grid 0:7e5081a3ed48 -0.17 -0.02 2018-2020 -cv-violet_grid 0:73f7bbf7cd60 -0.22 -0.05 juniorux/uidesigner|lumendigital -cv-violet_grid 0:c6b06045332f -0.05 -0.06 austin,tx -cv-violet_grid 0:5ea8234925c5 -0.14 0.05 supporteddiscoveryworkshops,user +cv-violet_grid 0:7e5081a3ed48 -0.29 -0.02 2018-2020 +cv-violet_grid 0:73f7bbf7cd60 -0.34 -0.05 juniorux/uidesigner|lumendigital +cv-violet_grid 0:c6b06045332f -0.17 -0.06 austin,tx +cv-violet_grid 0:5ea8234925c5 -0.26 0.05 supporteddiscoveryworkshops,user cv-violet_grid 0:46f00c76528c -0.19 0.05 designedresponsivewebsitesandlan -cv-violet_grid 0:f3cea36a9d83 -0.12 0.05 collaboratedwithcopywritersandde -cv-violet_grid 0:d94eccbb1fbe -0.17 -0.02 selectedprojects +cv-violet_grid 0:f3cea36a9d83 -0.24 0.05 collaboratedwithcopywritersandde +cv-violet_grid 0:d94eccbb1fbe -0.29 -0.02 selectedprojects cv-violet_grid 0:45dc8bf81211 -0.25 0.06 novafinmobileapp|personalfinance cv-violet_grid 0:d398b29d3dbb -0.17 0.48 2023 cv-violet_grid 0:e66c1ce573d3 -0.33 0.06 ledux/uidesignforbudgeting,goalt -cv-violet_grid 0:0ed8829e68d0 -0.29 0.06 thatinformedasimplifiednavigatio -cv-violet_grid 0:ee9bd17ebccf -0.25 0.06 22%increaseinweeklyactiveusers. +cv-violet_grid 0:0ed8829e68d0 -0.41 0.06 thatinformedasimplifiednavigatio +cv-violet_grid 0:ee9bd17ebccf -0.37 0.06 22%increaseinweeklyactiveusers. cv-violet_grid 0:28b4603d784a -0.25 0.06 brighthealthpatientportal|health cv-violet_grid 0:1bea20e1df19 -0.17 0.48 2021 -cv-violet_grid 0:999ddb26bed6 -0.33 0.06 redesignedkeypatientflowsincludi -cv-violet_grid 0:073d15633c0b -0.29 0.06 systemandcomponentlibraryusedacr +cv-violet_grid 0:999ddb26bed6 -0.45 0.06 redesignedkeypatientflowsincludi +cv-violet_grid 0:073d15633c0b -0.41 0.06 systemandcomponentlibraryusedacr cv-violet_grid 0:68bf0109c6f8 -0.07 -0.02 education cv-violet_grid 0:6cb574fa10b6 -0.07 0.12 languages -cv-violet_grid 0:0cf7506cf94a -0.07 0.01 bacheloroffineartsingraphicdesig -cv-violet_grid 0:00ab7a6aa5f1 -0.03 0.01 californiacollegeofthearts -cv-violet_grid 0:7e2c21bb41db -0.04 0.01 sanfrancisco,ca|2014-2018 -cv-violet_grid 0:b6234d2ea0d6 -1.38 0.04 english +cv-violet_grid 0:0cf7506cf94a -0.19 0.01 bacheloroffineartsingraphicdesig +cv-violet_grid 0:00ab7a6aa5f1 -0.15 0.01 californiacollegeofthearts +cv-violet_grid 0:7e2c21bb41db -0.16 0.01 sanfrancisco,ca|2014-2018 +cv-violet_grid 0:b6234d2ea0d6 -1.50 0.04 english cv-violet_grid 0:bef32d2c315a -1.37 0.08 native -cv-violet_grid 0:bef32d2c315a#1 -1.29 0.08 native -cv-violet_grid 0:9c9b13446cd9 -1.30 0.04 spanish -cv-violet_grid 0:e35242c809c8 -1.33 0.04 portuguese -cv-violet_grid 0:c5d1de4964d6 -1.20 0.08 conversational -cv-violet_grid 0:1de4fede4f63 -1.09 -0.38 idesignwithempathy,iteratewithpu +cv-violet_grid 0:bef32d2c315a#1 -1.41 0.08 native +cv-violet_grid 0:9c9b13446cd9 -1.42 0.04 spanish +cv-violet_grid 0:e35242c809c8 -1.45 0.04 portuguese +cv-violet_grid 0:c5d1de4964d6 -1.32 0.08 conversational +cv-violet_grid 0:1de4fede4f63 -1.21 -0.38 idesignwithempathy,iteratewithpu invoice-classic 0:c26c22b94338 0.51 0.00 graphcomposestudio invoice-classic 0:c26c22b94338#1 0.34 0.01 graphcomposestudio invoice-classic 0:2a08ce5567fb 0.41 0.00 18layoutstreet @@ -2643,7 +2644,7 @@ invoice-luma_studio_long 2:bc6d215b63ee 0.17 1.15 page3of3 invoice-merchant 0:0dffa3b5d008 0.00 0.10 coastline invoice-merchant 0:52d6e3de4fa0 0.07 0.77 invoice invoice-merchant 0:9422e2aeb800 0.14 0.03 coastlinecommerceinc. -invoice-merchant 0:9422e2aeb800#1 0.29 0.84 coastlinecommerceinc. +invoice-merchant 0:9422e2aeb800#1 0.17 0.84 coastlinecommerceinc. invoice-merchant 0:9422e2aeb800#2 -0.08 -0.01 coastlinecommerceinc. invoice-merchant 0:8bb83c0c3efb 0.08 0.03 150elginstreet,8thfloor invoice-merchant 0:cf0df3462e70 0.13 0.03 ottawa,onk2p1l4 @@ -2651,12 +2652,12 @@ invoice-merchant 0:408c7c5887a0 0.06 0.03 canada invoice-merchant 0:0d9b94d29fc9 0.00 0.00 www.coastline.example invoice-merchant 0:0d9b94d29fc9#1 -0.08 -0.01 www.coastline.example invoice-merchant 0:76957649b8a8 0.00 0.12 billing@coastline.example -invoice-merchant 0:76957649b8a8#1 0.35 0.84 billing@coastline.example +invoice-merchant 0:76957649b8a8#1 0.23 0.84 billing@coastline.example invoice-merchant 0:0b44bf19dd44 -0.12 0.12 +1613-555-0142 invoice-merchant 0:884004f21362 -0.06 0.03 vatid:ca8139020285rt0001 invoice-merchant 0:6282391a4cc1 0.21 0.08 invoicenumber: invoice-merchant 0:a6e01b979f55 0.21 0.06 inv-2026-000789 -invoice-merchant 0:a6e01b979f55#1 0.37 0.84 inv-2026-000789 +invoice-merchant 0:a6e01b979f55#1 0.25 0.84 inv-2026-000789 invoice-merchant 0:8d05f5d55191 0.22 0.08 invoicedate: invoice-merchant 0:dc9696f61d36 0.22 0.06 27may2026 invoice-merchant 0:0e0fb0fc0939 0.24 0.08 duedate: @@ -2707,23 +2708,23 @@ invoice-merchant 0:0036ebf2cfb2 -0.02 0.30 prioritysupport invoice-merchant 0:6bfa3f8e9308 -0.13 0.30 24/7support invoice-merchant 0:7f0f70e643bc 0.00 -0.16 included invoice-merchant 0:3c7ade679fdf 0.19 0.80 paymentdetails -invoice-merchant 0:944d398aea60 0.27 0.82 bankname: -invoice-merchant 0:d6c3cea2e943 0.27 0.84 harbourbankofcanada -invoice-merchant 0:0ecb5847ffa7 0.29 0.82 accountname: -invoice-merchant 0:6b4894c28363 0.35 0.82 accountnumber: -invoice-merchant 0:ca2ea6319cc8 0.35 0.84 1001-4267-153 +invoice-merchant 0:944d398aea60 0.15 0.82 bankname: +invoice-merchant 0:d6c3cea2e943 0.15 0.84 harbourbankofcanada +invoice-merchant 0:0ecb5847ffa7 0.17 0.82 accountname: +invoice-merchant 0:6b4894c28363 0.23 0.82 accountnumber: +invoice-merchant 0:ca2ea6319cc8 0.23 0.84 1001-4267-153 invoice-merchant 0:555043320c0c 0.25 0.82 swiftcode: invoice-merchant 0:922f5f70c123 0.25 0.84 hrbrcat2 -invoice-merchant 0:f1b1597830d6 0.27 0.82 institutionnumber: -invoice-merchant 0:88c0413bfef1 0.27 0.84 003 -invoice-merchant 0:e47c9313aced 0.30 0.82 transitnumber: -invoice-merchant 0:fec334e6bf8c 0.30 0.84 00016 -invoice-merchant 0:4f657c67e41a 0.32 0.82 accounttype: -invoice-merchant 0:b8b8acdf702e 0.32 0.84 cadaccount -invoice-merchant 0:fa0fbe194b51 0.35 0.82 remittanceemail: -invoice-merchant 0:c608665436db 0.37 0.82 reference: -invoice-merchant 0:1b0fdc20ced4 0.28 0.82 pleaseincludetheinvoicenumber -invoice-merchant 0:cfdf1faf410b 0.25 0.82 inyourpaymentreference. +invoice-merchant 0:f1b1597830d6 0.15 0.82 institutionnumber: +invoice-merchant 0:88c0413bfef1 0.15 0.84 003 +invoice-merchant 0:e47c9313aced 0.18 0.82 transitnumber: +invoice-merchant 0:fec334e6bf8c 0.18 0.84 00016 +invoice-merchant 0:4f657c67e41a 0.20 0.82 accounttype: +invoice-merchant 0:b8b8acdf702e 0.20 0.84 cadaccount +invoice-merchant 0:fa0fbe194b51 0.23 0.82 remittanceemail: +invoice-merchant 0:c608665436db 0.25 0.82 reference: +invoice-merchant 0:1b0fdc20ced4 0.16 0.82 pleaseincludetheinvoicenumber +invoice-merchant 0:cfdf1faf410b 0.13 0.82 inyourpaymentreference. invoice-merchant 0:d6577e95efba 0.19 0.06 subtotal invoice-merchant 0:30d16b02fd3e 0.26 0.96 444.00 invoice-merchant 0:2ee4d3de4ddf 0.19 0.06 tax(0%) @@ -2828,8 +2829,8 @@ invoice-metered 0:e50d8a0ea599 0.09 0.65 gbp42.94 invoice-metered 0:57a66d21eb1b -0.11 0.07 totaldue invoice-metered 0:f207312dff2f -0.19 0.09 gbp257.65 invoice-metered 0:b0553f008513 -0.02 0.12 paymentdueby -invoice-metered 0:e60e7ef06ccc -0.79 0.00 thankyouforrunningonnorthwindclo -invoice-metered 0:34ea2ec3fe72 -0.82 0.00 forbillingandaccountsupport,visi +invoice-metered 0:e60e7ef06ccc 0.17 0.00 thankyouforrunningonnorthwindclo +invoice-metered 0:34ea2ec3fe72 0.14 0.00 forbillingandaccountsupport,visi invoice-metered 0:e28672d64882 0.05 0.01 northwindcloudservicesltd.isasub invoice-metered 0:985e43c2de34 0.01 0.01 120riversideway,bristol,bs16qt,u invoice-metered 0:7b14b8d2c5c4 0.11 0.11 page1of1 @@ -3053,7 +3054,7 @@ invoice-obsidian 0:07f15cde5b18 0.11 -0.04 kestrel invoice-obsidian 0:52d6e3de4fa0 0.15 -0.04 invoice invoice-obsidian 0:5d1d1b79af09 -0.01 0.11 invoicenumber invoice-obsidian 0:3e62d1fbe5ec 0.06 0.11 inv-2026-1048 -invoice-obsidian 0:3e62d1fbe5ec#1 -0.36 0.06 inv-2026-1048 +invoice-obsidian 0:3e62d1fbe5ec#1 0.60 0.06 inv-2026-1048 invoice-obsidian 0:8feaf8016bab 0.08 0.11 issuedate invoice-obsidian 0:4d49cb78b810 0.08 -0.06 27august2026 invoice-obsidian 0:ac10f8c16320 -0.03 0.11 duedate @@ -3064,76 +3065,76 @@ invoice-obsidian 0:466e5b9cd57f -0.17 0.11 currency invoice-obsidian 0:54f8e1b3fe44 -0.17 0.52 gbp invoice-obsidian 0:75857a458999 -0.25 -0.02 from invoice-obsidian 0:7d7385ecfbd9 -0.21 0.01 kestrelbusiness -invoice-obsidian 0:7d7385ecfbd9#1 -0.33 0.06 kestrelbusiness -invoice-obsidian 0:7d7385ecfbd9#2 -0.09 -0.59 kestrelbusiness +invoice-obsidian 0:7d7385ecfbd9#1 0.63 0.06 kestrelbusiness +invoice-obsidian 0:7d7385ecfbd9#2 0.63 -0.59 kestrelbusiness invoice-obsidian 0:5f51304df361 -0.29 0.01 7harboursidewalk invoice-obsidian 0:895a6b59f677 -0.32 0.01 bristolbs15ty invoice-obsidian 0:2474519f77a9 -0.23 0.01 unitedkingdom invoice-obsidian 0:2474519f77a9#1 -0.23 0.10 unitedkingdom invoice-obsidian 0:70ec69d2102f -0.25 0.01 ar@kestrel.example -invoice-obsidian 0:70ec69d2102f#1 -0.16 -0.77 ar@kestrel.example +invoice-obsidian 0:70ec69d2102f#1 0.56 -0.77 ar@kestrel.example invoice-obsidian 0:aeba3a7b3598 -0.25 0.09 billto invoice-obsidian 0:7bfc2b791f41 -0.21 0.10 northlineconsultingltd invoice-obsidian 0:13dd937d2fe6 -0.29 0.10 21jubileeway invoice-obsidian 0:f9bab6a0b45b -0.32 0.10 londonse13ss -invoice-obsidian 0:c9046f7a37ad -1.81 0.70 description -invoice-obsidian 0:32e8369a9c4f -1.81 0.52 qty -invoice-obsidian 0:d1062d072acd -1.81 0.00 unitprice -invoice-obsidian 0:a52611c9261b -1.81 -0.18 vat(20%) -invoice-obsidian 0:a52611c9261b#1 -0.04 0.09 vat(20%) -invoice-obsidian 0:cf38d95c9c6b -1.81 0.16 amount -invoice-obsidian 0:15345cbad705 -0.38 0.70 subscriptionsetup -invoice-obsidian 0:5100476d46bb -0.40 0.70 one-offaccountandworkspacesetup -invoice-obsidian 0:507f9f133059 -0.47 0.09 £150.00 -invoice-obsidian 0:893d7480f763 -0.47 0.16 £30.00 -invoice-obsidian 0:893d7480f763#1 -0.78 0.18 £30.00 -invoice-obsidian 0:629184210581 -0.47 0.11 £180.00 -invoice-obsidian 0:3e8060178bc4 -0.40 0.70 internationalpaymentsupport -invoice-obsidian 0:33e4ab51097e -0.43 0.70 monthlysupportforcross-borderpay -invoice-obsidian 0:96d6b62c061d -0.49 0.09 £250.00 -invoice-obsidian 0:70d5b1312085 -0.49 0.16 £50.00 -invoice-obsidian 0:d86642b21e53 -0.49 0.11 £300.00 -invoice-obsidian 0:9399cf3b221a -0.53 0.70 expensemanagementintegration -invoice-obsidian 0:da2890c99f7a -0.43 0.70 apiaccessandintegration -invoice-obsidian 0:372ba7238228 -0.62 0.09 £200.00 -invoice-obsidian 0:05c6a4f7132f -0.62 0.16 £40.00 -invoice-obsidian 0:853580239989 -0.62 0.11 £240.00 -invoice-obsidian 0:ba80be228223 -0.55 0.70 virtualcards -invoice-obsidian 0:eae2564ef311 -0.57 0.70 50virtualcards -invoice-obsidian 0:cf02270203a4 -0.64 0.09 £100.00 -invoice-obsidian 0:33b5fc913817 -0.64 0.16 £20.00 -invoice-obsidian 0:8aec54fdb1a1 -0.64 0.11 £120.00 -invoice-obsidian 0:cc29e90932c5 -0.69 0.70 businessaccountmaintenance -invoice-obsidian 0:f1254de1a1d4 -0.72 0.70 monthlyaccountmaintenancefee -invoice-obsidian 0:8bf9ac7b27bd -0.78 0.24 £6.00 -invoice-obsidian 0:bff295cd3f97 -0.78 0.19 £36.00 -invoice-obsidian 0:d6577e95efba -0.06 0.09 subtotal -invoice-obsidian 0:4595e1b34cb1 -0.11 0.53 £730.00 -invoice-obsidian 0:eafa82a0eadf -0.10 0.53 £146.00 -invoice-obsidian 0:57a66d21eb1b -0.09 0.09 totaldue -invoice-obsidian 0:ad3ba615a506 -0.11 -0.66 £876.00 -invoice-obsidian 0:ab5aa97074c4 -0.36 0.01 notes -invoice-obsidian 0:0956d8d0441d -0.27 0.01 thankyouforchoosingkestrelbusine -invoice-obsidian 0:0b4d6f0e8783 -0.25 0.01 thisinvoicecoversservicesandfeat -invoice-obsidian 0:02e483554647 -0.22 0.01 toyourbusinessasofthedateofissue -invoice-obsidian 0:b439106fc5a1 -0.20 0.01 ifyouhaveanyquestionsaboutthisin -invoice-obsidian 0:877ac656a147 -0.30 0.01 pleasecontactusatar@kestrel.exam -invoice-obsidian 0:3c7ade679fdf -0.36 0.09 paymentdetails -invoice-obsidian 0:473fbeedb47c -0.91 0.09 pleasepaybybanktransfer -invoice-obsidian 0:59f2b74175d7 -0.94 0.09 totheaccountbelow. -invoice-obsidian 0:811f691f5582 -0.27 0.09 payee -invoice-obsidian 0:10aeacde20ff -0.35 0.09 sortcode -invoice-obsidian 0:a748c443f622 -0.42 0.06 04-00-75 -invoice-obsidian 0:f92a9c925024 -0.33 0.09 accountnumber -invoice-obsidian 0:ef797c8118f0 -0.39 0.06 12345678 -invoice-obsidian 0:52367a6622b1 -0.29 0.09 reference -invoice-obsidian 0:7c6ab37d83ef -0.07 0.02 thankyouforyourbusiness. -invoice-obsidian 0:a97667f07d1b -0.14 0.02 paymentisdueby10september2026. +invoice-obsidian 0:c9046f7a37ad -1.57 0.70 description +invoice-obsidian 0:32e8369a9c4f -1.57 0.52 qty +invoice-obsidian 0:d1062d072acd -1.57 0.00 unitprice +invoice-obsidian 0:a52611c9261b -1.57 -0.18 vat(20%) +invoice-obsidian 0:a52611c9261b#1 0.56 0.09 vat(20%) +invoice-obsidian 0:cf38d95c9c6b -1.57 0.16 amount +invoice-obsidian 0:15345cbad705 -0.14 0.70 subscriptionsetup +invoice-obsidian 0:5100476d46bb -0.16 0.70 one-offaccountandworkspacesetup +invoice-obsidian 0:507f9f133059 -0.23 0.09 £150.00 +invoice-obsidian 0:893d7480f763 -0.23 0.16 £30.00 +invoice-obsidian 0:893d7480f763#1 -0.54 0.18 £30.00 +invoice-obsidian 0:629184210581 -0.23 0.11 £180.00 +invoice-obsidian 0:3e8060178bc4 -0.16 0.70 internationalpaymentsupport +invoice-obsidian 0:33e4ab51097e -0.19 0.70 monthlysupportforcross-borderpay +invoice-obsidian 0:96d6b62c061d -0.25 0.09 £250.00 +invoice-obsidian 0:70d5b1312085 -0.25 0.16 £50.00 +invoice-obsidian 0:d86642b21e53 -0.25 0.11 £300.00 +invoice-obsidian 0:9399cf3b221a -0.17 0.70 expensemanagementintegration +invoice-obsidian 0:da2890c99f7a -0.19 0.70 apiaccessandintegration +invoice-obsidian 0:372ba7238228 -0.26 0.09 £200.00 +invoice-obsidian 0:05c6a4f7132f -0.26 0.16 £40.00 +invoice-obsidian 0:853580239989 -0.26 0.11 £240.00 +invoice-obsidian 0:ba80be228223 -0.19 0.70 virtualcards +invoice-obsidian 0:eae2564ef311 -0.21 0.70 50virtualcards +invoice-obsidian 0:cf02270203a4 -0.28 0.09 £100.00 +invoice-obsidian 0:33b5fc913817 -0.28 0.16 £20.00 +invoice-obsidian 0:8aec54fdb1a1 -0.28 0.11 £120.00 +invoice-obsidian 0:cc29e90932c5 -0.45 0.70 businessaccountmaintenance +invoice-obsidian 0:f1254de1a1d4 -0.48 0.70 monthlyaccountmaintenancefee +invoice-obsidian 0:8bf9ac7b27bd -0.54 0.24 £6.00 +invoice-obsidian 0:bff295cd3f97 -0.54 0.19 £36.00 +invoice-obsidian 0:d6577e95efba 0.54 0.09 subtotal +invoice-obsidian 0:4595e1b34cb1 0.61 0.53 £730.00 +invoice-obsidian 0:eafa82a0eadf 0.50 0.53 £146.00 +invoice-obsidian 0:57a66d21eb1b 0.51 0.09 totaldue +invoice-obsidian 0:ad3ba615a506 0.49 -0.66 £876.00 +invoice-obsidian 0:ab5aa97074c4 0.72 0.01 notes +invoice-obsidian 0:0956d8d0441d 0.81 0.01 thankyouforchoosingkestrelbusine +invoice-obsidian 0:0b4d6f0e8783 0.83 0.01 thisinvoicecoversservicesandfeat +invoice-obsidian 0:02e483554647 0.74 0.01 toyourbusinessasofthedateofissue +invoice-obsidian 0:b439106fc5a1 0.76 0.01 ifyouhaveanyquestionsaboutthisin +invoice-obsidian 0:877ac656a147 0.78 0.01 pleasecontactusatar@kestrel.exam +invoice-obsidian 0:3c7ade679fdf 0.72 0.09 paymentdetails +invoice-obsidian 0:473fbeedb47c 0.17 0.09 pleasepaybybanktransfer +invoice-obsidian 0:59f2b74175d7 0.14 0.09 totheaccountbelow. +invoice-obsidian 0:811f691f5582 0.69 0.09 payee +invoice-obsidian 0:10aeacde20ff 0.73 0.09 sortcode +invoice-obsidian 0:a748c443f622 0.66 0.06 04-00-75 +invoice-obsidian 0:f92a9c925024 0.75 0.09 accountnumber +invoice-obsidian 0:ef797c8118f0 0.69 0.06 12345678 +invoice-obsidian 0:52367a6622b1 0.67 0.09 reference +invoice-obsidian 0:7c6ab37d83ef 0.65 0.02 thankyouforyourbusiness. +invoice-obsidian 0:a97667f07d1b 0.58 0.02 paymentisdueby10september2026. invoice-obsidian 0:7b14b8d2c5c4 0.10 -0.55 page1of1 invoice-payments 0:b6c4ac412ac8 0.00 -0.03 meridian invoice-payments 0:52d6e3de4fa0 0.05 0.12 invoice invoice-payments 0:c0cc75b9cfdc -0.19 0.06 meridianpaymentsltd. -invoice-payments 0:c0cc75b9cfdc#1 0.05 0.05 meridianpaymentsltd. +invoice-payments 0:c0cc75b9cfdc#1 -0.07 0.05 meridianpaymentsltd. invoice-payments 0:5eeaa101da6c -0.13 0.06 1harbourexchange invoice-payments 0:e3f6090f249b -0.17 0.06 canarywharf invoice-payments 0:1bb9adbf32ff -0.20 0.06 londone149ge @@ -3150,7 +3151,7 @@ invoice-payments 0:fb854bac39c8 -0.13 0.12 paymentterms invoice-payments 0:ac10f8c16320 -0.12 0.12 duedate invoice-payments 0:073c1634c496 -0.10 0.12 status invoice-payments 0:052ff4dff688 0.08 0.08 inv-2025-05-10472 -invoice-payments 0:052ff4dff688#1 -0.16 0.05 inv-2025-05-10472 +invoice-payments 0:052ff4dff688#1 -0.28 0.05 inv-2025-05-10472 invoice-payments 0:23a4c624cbda 0.10 0.08 10may2025 invoice-payments 0:7b052c343b27 0.11 0.08 1-30april2025 invoice-payments 0:018052c1dd59 0.13 0.08 acct_4q8xtb2mkp @@ -3175,77 +3176,77 @@ invoice-payments 0:7c512b48ba8a 0.09 0.30 vat invoice-payments 0:2da123241332 0.09 1.03 amount(gbp) invoice-payments 0:3ab6c1099bcc 0.07 0.40 subscriptionbilling invoice-payments 0:c8e69cd6e074 0.24 0.40 subscriptionmanagementandrecurri -invoice-payments 0:0c95c7ece1ce 0.16 0.40 billing -invoice-payments 0:96d6b62c061d 0.06 -0.30 £250.00 -invoice-payments 0:96d6b62c061d#1 0.14 0.73 £250.00 -invoice-payments 0:dc934fe30a94 0.06 0.17 20% -invoice-payments 0:dc934fe30a94#1 0.11 0.17 20% -invoice-payments 0:dc934fe30a94#2 0.15 0.17 20% -invoice-payments 0:dc934fe30a94#3 0.15 0.17 20% +invoice-payments 0:0c95c7ece1ce 0.04 0.40 billing +invoice-payments 0:96d6b62c061d -0.06 -0.30 £250.00 +invoice-payments 0:96d6b62c061d#1 0.02 0.73 £250.00 +invoice-payments 0:dc934fe30a94 -0.06 0.17 20% +invoice-payments 0:dc934fe30a94#1 -0.01 0.17 20% +invoice-payments 0:dc934fe30a94#2 0.03 0.17 20% +invoice-payments 0:dc934fe30a94#3 0.03 0.17 20% invoice-payments 0:dc934fe30a94#4 0.03 0.17 20% invoice-payments 0:dc934fe30a94#5 0.02 0.17 20% -invoice-payments 0:0a9acaea6477 0.12 0.40 paymentprocessing -invoice-payments 0:b8a3c21545b4 0.28 0.40 onlinecardpaymentsprocessing +invoice-payments 0:0a9acaea6477 0.00 0.40 paymentprocessing +invoice-payments 0:b8a3c21545b4 0.16 0.40 onlinecardpaymentsprocessing invoice-payments 0:b42561a38a06 0.08 0.40 (volumetier) -invoice-payments 0:351704ebff51 0.11 -0.39 £1,180.00 -invoice-payments 0:351704ebff51#1 0.06 0.71 £1,180.00 -invoice-payments 0:b3bc34f90a55 0.12 0.40 fraudscreening -invoice-payments 0:ed051c6a1942 0.16 0.40 advancedfraudscreeningandrules -invoice-payments 0:a0a787efd867 0.15 -0.30 £320.00 -invoice-payments 0:a0a787efd867#1 0.10 0.73 £320.00 -invoice-payments 0:34b75c1d0234 0.12 0.40 companyformation -invoice-payments 0:bf45c494a8dc 0.16 0.40 incorporationandcompliancefiling -invoice-payments 0:629184210581 0.15 -0.30 £180.00 -invoice-payments 0:629184210581#1 0.10 0.73 £180.00 -invoice-payments 0:9427a01801d2 0.12 0.40 in-personterminals -invoice-payments 0:882be821cf2e 0.16 0.40 terminalrentalandfirmwareupdates +invoice-payments 0:351704ebff51 -0.01 -0.39 £1,180.00 +invoice-payments 0:351704ebff51#1 -0.06 0.71 £1,180.00 +invoice-payments 0:b3bc34f90a55 0.00 0.40 fraudscreening +invoice-payments 0:ed051c6a1942 0.04 0.40 advancedfraudscreeningandrules +invoice-payments 0:a0a787efd867 0.03 -0.30 £320.00 +invoice-payments 0:a0a787efd867#1 -0.02 0.73 £320.00 +invoice-payments 0:34b75c1d0234 0.00 0.40 companyformation +invoice-payments 0:bf45c494a8dc 0.04 0.40 incorporationandcompliancefiling +invoice-payments 0:629184210581 0.03 -0.30 £180.00 +invoice-payments 0:629184210581#1 -0.02 0.73 £180.00 +invoice-payments 0:9427a01801d2 0.00 0.40 in-personterminals +invoice-payments 0:882be821cf2e 0.04 0.40 terminalrentalandfirmwareupdates invoice-payments 0:3c4459a5e4ec 0.03 -0.13 £39.00 -invoice-payments 0:5d16afda896e 0.10 0.73 £156.00 -invoice-payments 0:0036ebf2cfb2 0.12 0.40 prioritysupport -invoice-payments 0:7ef1d2ff5e3a 0.16 0.40 namedengineer,one-hourresponse +invoice-payments 0:5d16afda896e -0.02 0.73 £156.00 +invoice-payments 0:0036ebf2cfb2 0.00 0.40 prioritysupport +invoice-payments 0:7ef1d2ff5e3a 0.04 0.40 namedengineer,one-hourresponse invoice-payments 0:cf02270203a4 0.02 -0.30 £100.00 -invoice-payments 0:cf02270203a4#1 0.10 0.73 £100.00 -invoice-payments 0:3c7ade679fdf 0.01 0.12 paymentdetails -invoice-payments 0:182748d2fece 0.09 0.09 bankname -invoice-payments 0:758f4a6f175f 0.15 0.09 accountname -invoice-payments 0:10aeacde20ff 0.18 0.09 sortcode +invoice-payments 0:cf02270203a4#1 -0.02 0.73 £100.00 +invoice-payments 0:3c7ade679fdf -0.11 0.12 paymentdetails +invoice-payments 0:182748d2fece -0.03 0.09 bankname +invoice-payments 0:758f4a6f175f 0.03 0.09 accountname +invoice-payments 0:10aeacde20ff 0.06 0.09 sortcode invoice-payments 0:f92a9c925024 0.09 0.09 accountnumber -invoice-payments 0:d53cd2cae33d 0.12 0.09 iban -invoice-payments 0:3f695692d5f1 0.15 0.09 swift/bic -invoice-payments 0:52367a6622b1 0.18 0.09 reference -invoice-payments 0:c66da4639881 0.11 0.05 harbourbankplc -invoice-payments 0:2cd71c3c2603 -0.04 0.05 40-02-50 +invoice-payments 0:d53cd2cae33d 0.00 0.09 iban +invoice-payments 0:3f695692d5f1 0.03 0.09 swift/bic +invoice-payments 0:52367a6622b1 0.06 0.09 reference +invoice-payments 0:c66da4639881 -0.01 0.05 harbourbankplc +invoice-payments 0:2cd71c3c2603 -0.16 0.05 40-02-50 invoice-payments 0:8fb8a81278c4 -0.13 0.05 71295408 -invoice-payments 0:48617b6d05d4 -0.10 0.05 gb29hrbk40025071295408 -invoice-payments 0:6929e6db6e1f -0.19 0.05 hrbkgb2l -invoice-payments 0:e4c4788968b2 0.18 0.03 subtotal(excl.vat) -invoice-payments 0:7ed180496d4e 0.25 0.03 vatat20% -invoice-payments 0:751cbab81a3a 0.25 0.22 £2,186.00 -invoice-payments 0:9a5256946abd 0.32 0.93 £437.20 -invoice-payments 0:57a66d21eb1b 0.17 0.03 totaldue -invoice-payments 0:5eb0b17220fa 0.15 0.03 dueby14june2025 -invoice-payments 0:30d896eb989f -0.08 -0.83 £2,623.20 -invoice-payments 0:ab5aa97074c4 0.41 0.09 notes -invoice-payments 0:241bcf576ac5 0.32 0.09 thankyouforyourbusiness.thisinvo -invoice-payments 0:f912ca46bf39 0.26 0.09 latepaymentmayincurinterestatthe -invoice-payments 0:73a09fec2c1a 0.38 0.07 paymentdueby14june2025 -invoice-payments 0:79df6c5bbc16 0.38 0.07 pleaseincludetheinvoicenumberasp -invoice-payments 0:28b3008f693b 0.43 0.11 questions?we'reheretohelp. -invoice-payments 0:5b88ed40a689 0.32 0.11 support@meridianpayments.example -invoice-payments 0:2e3891f6ba2f 0.30 0.11 39661900 +invoice-payments 0:48617b6d05d4 -0.22 0.05 gb29hrbk40025071295408 +invoice-payments 0:6929e6db6e1f -0.31 0.05 hrbkgb2l +invoice-payments 0:e4c4788968b2 0.06 0.03 subtotal(excl.vat) +invoice-payments 0:7ed180496d4e 0.13 0.03 vatat20% +invoice-payments 0:751cbab81a3a 0.13 0.22 £2,186.00 +invoice-payments 0:9a5256946abd 0.20 0.93 £437.20 +invoice-payments 0:57a66d21eb1b 0.05 0.03 totaldue +invoice-payments 0:5eb0b17220fa 0.03 0.03 dueby14june2025 +invoice-payments 0:30d896eb989f -0.20 -0.83 £2,623.20 +invoice-payments 0:ab5aa97074c4 0.17 0.09 notes +invoice-payments 0:241bcf576ac5 0.20 0.09 thankyouforyourbusiness.thisinvo +invoice-payments 0:f912ca46bf39 0.14 0.09 latepaymentmayincurinterestatthe +invoice-payments 0:73a09fec2c1a 0.14 0.07 paymentdueby14june2025 +invoice-payments 0:79df6c5bbc16 0.14 0.07 pleaseincludetheinvoicenumberasp +invoice-payments 0:28b3008f693b 0.19 0.11 questions?we'reheretohelp. +invoice-payments 0:5b88ed40a689 0.20 0.11 support@meridianpayments.example +invoice-payments 0:2e3891f6ba2f 0.18 0.11 39661900 invoice-payments 0:7b14b8d2c5c4 0.06 -0.20 page1of1 invoice-platform 0:9817f28442bf -0.07 -0.02 auroracloud invoice-platform 0:9817f28442bf#1 -0.46 0.00 auroracloud invoice-platform 0:52d6e3de4fa0 0.18 -0.24 invoice invoice-platform 0:1cf61cdc6464 -0.14 -0.03 auroracloudinc. -invoice-platform 0:1cf61cdc6464#1 0.02 0.71 auroracloudinc. +invoice-platform 0:1cf61cdc6464#1 -0.10 0.71 auroracloudinc. invoice-platform 0:1cf61cdc6464#2 -0.43 0.31 auroracloudinc. invoice-platform 0:43315277b007 -0.38 -0.03 500harbourstreet invoice-platform 0:d9065bfb8f59 -0.33 -0.03 vancouver,bcv6c2w2 invoice-platform 0:408c7c5887a0 -0.41 -0.03 canada invoice-platform 0:88a643f14708 0.06 0.05 aurora.example invoice-platform 0:f2cfc804c0f3 0.07 0.05 billing@aurora.example -invoice-platform 0:f2cfc804c0f3#1 0.05 0.71 billing@aurora.example +invoice-platform 0:f2cfc804c0f3#1 -0.07 0.71 billing@aurora.example invoice-platform 0:799715f2b96e 0.09 0.05 +1604-555-0180 invoice-platform 0:719c55c7e988 -0.46 -0.03 vatid:cabn842137755 invoice-platform 0:6282391a4cc1 -0.29 0.33 invoicenumber: @@ -3318,22 +3319,22 @@ invoice-platform 0:561b2814d3c0#1 -0.17 0.31 0.00 invoice-platform 0:efa8771baad9 -0.22 -0.01 supportplan invoice-platform 0:9e81cd6e653a -0.12 -0.01 standardresponse invoice-platform 0:13000a5d442c -0.15 0.67 paymentinformation -invoice-platform 0:944d398aea60 0.00 0.69 bankname: -invoice-platform 0:d6c3cea2e943 0.00 0.71 harbourbankofcanada -invoice-platform 0:0ecb5847ffa7 0.02 0.69 accountname: -invoice-platform 0:6b4894c28363 0.00 0.69 accountnumber: -invoice-platform 0:559c58c48948 0.00 0.71 417802336 -invoice-platform 0:555043320c0c -0.01 0.69 swiftcode: -invoice-platform 0:5a986aa9e713 -0.01 0.71 hbcacat1 +invoice-platform 0:944d398aea60 -0.12 0.69 bankname: +invoice-platform 0:d6c3cea2e943 -0.12 0.71 harbourbankofcanada +invoice-platform 0:0ecb5847ffa7 -0.10 0.69 accountname: +invoice-platform 0:6b4894c28363 -0.12 0.69 accountnumber: +invoice-platform 0:559c58c48948 -0.12 0.71 417802336 +invoice-platform 0:555043320c0c -0.13 0.69 swiftcode: +invoice-platform 0:5a986aa9e713 -0.13 0.71 hbcacat1 invoice-platform 0:e47c9313aced -0.02 0.69 transitnumber: invoice-platform 0:20b565bff5c3 -0.02 0.71 00812 -invoice-platform 0:f1b1597830d6 0.08 0.69 institutionnumber: -invoice-platform 0:3c241d267414 0.08 0.71 049 -invoice-platform 0:4f657c67e41a 0.07 0.69 accounttype: -invoice-platform 0:7522b6a6c098 0.07 0.71 businesschequing -invoice-platform 0:fa0fbe194b51 0.05 0.69 remittanceemail: -invoice-platform 0:b3ec04f337ed -0.02 0.58 includeyourbillingaccountid -invoice-platform 0:a11a3e122422 -0.07 0.58 onyourpaymentremittance. +invoice-platform 0:f1b1597830d6 -0.04 0.69 institutionnumber: +invoice-platform 0:3c241d267414 -0.04 0.71 049 +invoice-platform 0:4f657c67e41a -0.05 0.69 accounttype: +invoice-platform 0:7522b6a6c098 -0.05 0.71 businesschequing +invoice-platform 0:fa0fbe194b51 -0.07 0.69 remittanceemail: +invoice-platform 0:b3ec04f337ed -0.14 0.58 includeyourbillingaccountid +invoice-platform 0:a11a3e122422 -0.19 0.58 onyourpaymentremittance. invoice-platform 0:d6577e95efba -0.15 0.02 subtotal invoice-platform 0:6fb943a5640a -0.15 -0.05 186.44 invoice-platform 0:26a72d1933a2 -0.10 0.02 tax(5%) @@ -3351,14 +3352,14 @@ invoice-subscription 0:0a36c1665b7e 0.31 0.04 halsteadsoftwareltd. invoice-subscription 0:6bc2056359b7 0.30 0.04 18chandlerrow invoice-subscription 0:776a7e9eb92a 0.31 0.04 leedsls14qt invoice-subscription 0:2474519f77a9 0.31 0.04 unitedkingdom -invoice-subscription 0:2474519f77a9#1 -0.63 0.04 unitedkingdom -invoice-subscription 0:2474519f77a9#2 -0.63 0.12 unitedkingdom +invoice-subscription 0:2474519f77a9#1 0.57 0.04 unitedkingdom +invoice-subscription 0:2474519f77a9#2 0.57 0.12 unitedkingdom invoice-subscription 0:bfdec553b85a 0.32 0.04 billing@halstead.example invoice-subscription 0:78acb3cb907b 0.32 0.04 www.halstead.example invoice-subscription 0:f1c030eb4329 0.43 0.04 vatnogb418227603 invoice-subscription 0:77ead61b5875 0.37 0.06 invoiceno invoice-subscription 0:0b0c0ee24de8 0.34 0.68 hs-inv-2026-0417 -invoice-subscription 0:0b0c0ee24de8#1 0.08 1.48 hs-inv-2026-0417 +invoice-subscription 0:0b0c0ee24de8#1 0.80 1.48 hs-inv-2026-0417 invoice-subscription 0:8feaf8016bab 0.32 0.06 issuedate invoice-subscription 0:4d49cb78b810 0.41 0.60 27august2026 invoice-subscription 0:ac10f8c16320 0.39 0.06 duedate @@ -3368,77 +3369,77 @@ invoice-subscription 0:56a2e019b8aa 0.44 0.36 14days invoice-subscription 0:466e5b9cd57f 0.54 0.06 currency invoice-subscription 0:54f8e1b3fe44 0.51 0.24 gbp invoice-subscription 0:aeba3a7b3598 0.59 0.04 billto -invoice-subscription 0:7bfc2b791f41 -0.66 0.04 northlineconsultingltd -invoice-subscription 0:7bfc2b791f41#1 -0.66 0.12 northlineconsultingltd -invoice-subscription 0:bcb7024f74fe -0.65 0.04 attn:sarahmitchell -invoice-subscription 0:13dd937d2fe6 -0.64 0.04 21jubileeway -invoice-subscription 0:f9bab6a0b45b -0.64 0.04 londonse13ss +invoice-subscription 0:7bfc2b791f41 0.42 0.04 northlineconsultingltd +invoice-subscription 0:7bfc2b791f41#1 0.42 0.12 northlineconsultingltd +invoice-subscription 0:bcb7024f74fe 0.55 0.04 attn:sarahmitchell +invoice-subscription 0:13dd937d2fe6 0.56 0.04 21jubileeway +invoice-subscription 0:f9bab6a0b45b 0.56 0.04 londonse13ss invoice-subscription 0:725a8f5062e7 0.59 0.12 shipto -invoice-subscription 0:254289ce0191 -0.65 0.12 thefoundry,2ndfloor -invoice-subscription 0:84db1f48facb -0.64 0.12 17-19greatsuffolkstreet -invoice-subscription 0:e7a5f0717d99 -0.64 0.12 londonse10ns -invoice-subscription 0:c9046f7a37ad -0.60 0.06 description -invoice-subscription 0:32e8369a9c4f -0.60 0.04 qty -invoice-subscription 0:d1062d072acd -0.60 0.01 unitprice -invoice-subscription 0:7c512b48ba8a -0.60 0.08 vat -invoice-subscription 0:cf38d95c9c6b -0.60 0.01 amount -invoice-subscription 0:86705447c73d -0.23 0.06 halsteadworkspacepremium(10seats -invoice-subscription 0:0c8dc980db3f -0.23 0.06 £18.00 -invoice-subscription 0:dc934fe30a94 -0.23 0.11 20% -invoice-subscription 0:dc934fe30a94#1 -0.16 0.11 20% -invoice-subscription 0:dc934fe30a94#2 -0.19 0.11 20% -invoice-subscription 0:dc934fe30a94#3 -0.12 0.11 20% -invoice-subscription 0:dc934fe30a94#4 -0.17 0.11 20% -invoice-subscription 0:629184210581 -0.23 0.10 £180.00 -invoice-subscription 0:59df1d2b0f69 -0.16 0.06 hostedplatformservices -invoice-subscription 0:44c1ce3394d2 -0.16 0.01 £420.00 -invoice-subscription 0:44c1ce3394d2#1 -0.16 0.11 £420.00 -invoice-subscription 0:217bada1d20f -0.19 0.06 analyticsprolicences(5seats) -invoice-subscription 0:599cd58953ce -0.19 0.02 £8.40 -invoice-subscription 0:756b8c62fe05 -0.19 0.16 £42.00 -invoice-subscription 0:b055bcc305ed -0.12 0.06 prioritysupportplan -invoice-subscription 0:1077d7cede59 -0.12 0.09 £275.00 -invoice-subscription 0:1077d7cede59#1 -0.12 0.19 £275.00 -invoice-subscription 0:361537ef6a11 -0.17 0.06 voiceadd-on(5seats) -invoice-subscription 0:8bf9ac7b27bd -0.17 0.12 £6.00 -invoice-subscription 0:893d7480f763 -0.17 0.18 £30.00 -invoice-subscription 0:ab5aa97074c4 0.08 0.04 notes -invoice-subscription 0:4440ed73b83f 0.76 0.04 thisinvoicecoverssoftwaresubscri -invoice-subscription 0:fffc319556fa 0.88 0.04 hostedservicesforthecurrentbilli -invoice-subscription 0:d6577e95efba -0.15 0.12 subtotal -invoice-subscription 0:adde9b2bd3ad -0.15 0.34 £947.00 -invoice-subscription 0:a52611c9261b -0.07 0.12 vat(20%) -invoice-subscription 0:14edcfc20351 -0.07 0.35 £189.40 -invoice-subscription 0:57a66d21eb1b -0.10 0.12 totaldue -invoice-subscription 0:cf1b68cc49ef -0.01 0.80 £1,136.40 -invoice-subscription 0:3c7ade679fdf 1.33 0.04 paymentdetails -invoice-subscription 0:56ed021beb35 0.14 0.19 beneficiary -invoice-subscription 0:0b85f3c8ed04 0.08 0.20 halsteadsoftwareltd -invoice-subscription 0:4381dc2ab142 0.14 0.77 bank -invoice-subscription 0:6d50b2dd724f 0.08 0.94 northgatebank -invoice-subscription 0:10aeacde20ff 0.14 1.06 sortcode -invoice-subscription 0:b19b1415ef9b 0.08 1.16 40-05-30 -invoice-subscription 0:f92a9c925024 0.14 1.23 accountnumber -invoice-subscription 0:ef797c8118f0 0.08 1.23 12345678 -invoice-subscription 0:52367a6622b1 0.14 1.43 reference -invoice-subscription 0:04f7247e8e99 0.14 0.04 pleaseincludetheinvoicenumberast -invoice-subscription 0:7c6ab37d83ef 0.17 0.01 thankyouforyourbusiness. -invoice-subscription 0:354ffeb2bbc3 0.07 0.01 paymentisdueby10september2026.if -invoice-subscription 0:7f7d98088133 0.09 0.01 foranyqueries,pleasecontactbilli +invoice-subscription 0:254289ce0191 0.55 0.12 thefoundry,2ndfloor +invoice-subscription 0:84db1f48facb 0.56 0.12 17-19greatsuffolkstreet +invoice-subscription 0:e7a5f0717d99 0.56 0.12 londonse10ns +invoice-subscription 0:c9046f7a37ad 0.60 0.06 description +invoice-subscription 0:32e8369a9c4f 0.60 0.04 qty +invoice-subscription 0:d1062d072acd 0.60 0.01 unitprice +invoice-subscription 0:7c512b48ba8a 0.60 0.08 vat +invoice-subscription 0:cf38d95c9c6b 0.60 0.01 amount +invoice-subscription 0:86705447c73d 0.97 0.06 halsteadworkspacepremium(10seats +invoice-subscription 0:0c8dc980db3f 0.97 0.06 £18.00 +invoice-subscription 0:dc934fe30a94 0.97 0.11 20% +invoice-subscription 0:dc934fe30a94#1 0.92 0.11 20% +invoice-subscription 0:dc934fe30a94#2 1.01 0.11 20% +invoice-subscription 0:dc934fe30a94#3 0.96 0.11 20% +invoice-subscription 0:dc934fe30a94#4 1.03 0.11 20% +invoice-subscription 0:629184210581 0.97 0.10 £180.00 +invoice-subscription 0:59df1d2b0f69 0.92 0.06 hostedplatformservices +invoice-subscription 0:44c1ce3394d2 0.92 0.01 £420.00 +invoice-subscription 0:44c1ce3394d2#1 0.92 0.11 £420.00 +invoice-subscription 0:217bada1d20f 1.01 0.06 analyticsprolicences(5seats) +invoice-subscription 0:599cd58953ce 1.01 0.02 £8.40 +invoice-subscription 0:756b8c62fe05 1.01 0.16 £42.00 +invoice-subscription 0:b055bcc305ed 0.96 0.06 prioritysupportplan +invoice-subscription 0:1077d7cede59 0.96 0.09 £275.00 +invoice-subscription 0:1077d7cede59#1 0.96 0.19 £275.00 +invoice-subscription 0:361537ef6a11 1.03 0.06 voiceadd-on(5seats) +invoice-subscription 0:8bf9ac7b27bd 1.03 0.12 £6.00 +invoice-subscription 0:893d7480f763 1.03 0.18 £30.00 +invoice-subscription 0:ab5aa97074c4 0.92 0.04 notes +invoice-subscription 0:4440ed73b83f 0.52 0.04 thisinvoicecoverssoftwaresubscri +invoice-subscription 0:fffc319556fa 0.52 0.04 hostedservicesforthecurrentbilli +invoice-subscription 0:d6577e95efba 0.69 0.12 subtotal +invoice-subscription 0:adde9b2bd3ad 0.69 0.34 £947.00 +invoice-subscription 0:a52611c9261b 0.77 0.12 vat(20%) +invoice-subscription 0:14edcfc20351 0.77 0.35 £189.40 +invoice-subscription 0:57a66d21eb1b 0.74 0.12 totaldue +invoice-subscription 0:cf1b68cc49ef 0.95 0.80 £1,136.40 +invoice-subscription 0:3c7ade679fdf 0.97 0.04 paymentdetails +invoice-subscription 0:56ed021beb35 0.86 0.19 beneficiary +invoice-subscription 0:0b85f3c8ed04 0.80 0.20 halsteadsoftwareltd +invoice-subscription 0:4381dc2ab142 0.86 0.77 bank +invoice-subscription 0:6d50b2dd724f 0.80 0.94 northgatebank +invoice-subscription 0:10aeacde20ff 0.86 1.06 sortcode +invoice-subscription 0:b19b1415ef9b 0.80 1.16 40-05-30 +invoice-subscription 0:f92a9c925024 0.86 1.23 accountnumber +invoice-subscription 0:ef797c8118f0 0.80 1.23 12345678 +invoice-subscription 0:52367a6622b1 0.86 1.43 reference +invoice-subscription 0:04f7247e8e99 0.86 0.04 pleaseincludetheinvoicenumberast +invoice-subscription 0:7c6ab37d83ef 0.89 0.01 thankyouforyourbusiness. +invoice-subscription 0:354ffeb2bbc3 0.79 0.01 paymentisdueby10september2026.if +invoice-subscription 0:7f7d98088133 0.81 0.01 foranyqueries,pleasecontactbilli invoice-subscription 0:7b14b8d2c5c4 0.09 0.04 page1of1 invoice-workspace 0:07f15cde5b18 -0.12 0.05 kestrel -invoice-workspace 0:07f15cde5b18#1 0.82 0.05 kestrel +invoice-workspace 0:07f15cde5b18#1 -0.14 0.05 kestrel invoice-workspace 0:52d6e3de4fa0 -0.10 0.46 invoice invoice-workspace 0:091019880d88 -0.31 0.12 kestrelcollaboration,inc. -invoice-workspace 0:091019880d88#1 0.54 0.00 kestrelcollaboration,inc. -invoice-workspace 0:091019880d88#2 0.66 0.06 kestrelcollaboration,inc. +invoice-workspace 0:091019880d88#1 -0.18 0.00 kestrelcollaboration,inc. +invoice-workspace 0:091019880d88#2 -0.30 0.06 kestrelcollaboration,inc. invoice-workspace 0:9167e0470dae -0.22 0.12 500howardstreet,6thfloor invoice-workspace 0:efa5e1529794 -0.26 0.12 sanfrancisco,ca94105 invoice-workspace 0:fd7321c405f8 -0.17 0.12 unitedstates invoice-workspace 0:d3c6f273c22d -0.14 0.00 vatid:us77-0560185 invoice-workspace 0:6282391a4cc1 -0.30 0.10 invoicenumber: invoice-workspace 0:b13757c9a6fc -0.21 0.08 inv-2024-0003521 -invoice-workspace 0:b13757c9a6fc#1 0.35 0.00 inv-2024-0003521 +invoice-workspace 0:b13757c9a6fc#1 -0.37 0.00 inv-2024-0003521 invoice-workspace 0:8d05f5d55191 -0.33 0.10 invoicedate: invoice-workspace 0:8da43dd45024 -0.23 0.08 27may2024 invoice-workspace 0:d39366fa1423 -0.23 0.10 billingperiod: @@ -3449,7 +3450,7 @@ invoice-workspace 0:18e2cca1098e -0.16 0.10 paymentterms: invoice-workspace 0:98ec3d1fd5b9 -0.19 0.08 net30 invoice-workspace 0:0e0fb0fc0939 -0.19 0.10 duedate: invoice-workspace 0:f1e2a60122bd -0.10 0.08 26june2024 -invoice-workspace 0:f1e2a60122bd#1 -0.47 0.15 26june2024 +invoice-workspace 0:f1e2a60122bd#1 -0.11 0.15 26june2024 invoice-workspace 0:aeba3a7b3598 -0.12 0.06 billto invoice-workspace 0:45fe04dbae24 -0.11 0.06 brightfutureltd. invoice-workspace 0:45fe04dbae24#1 -0.11 0.02 brightfutureltd. @@ -3461,60 +3462,60 @@ invoice-workspace 0:c7a9cfdd1c55 -0.05 0.06 vatid:gb987654321 invoice-workspace 0:725a8f5062e7 -0.12 0.14 shipto invoice-workspace 0:6d835e737af6 -0.14 0.02 unit4,riversidepark invoice-workspace 0:555d5194cd4d -0.10 0.02 leedsls14ap -invoice-workspace 0:c9046f7a37ad 0.04 0.43 description -invoice-workspace 0:169240d91658 0.04 0.21 plan/service -invoice-workspace 0:32e8369a9c4f 0.04 0.14 qty -invoice-workspace 0:e2a9c81da5f6 0.04 0.24 unitprice(usd) -invoice-workspace 0:5dfb966b2bcf 0.04 0.44 amount(usd) +invoice-workspace 0:c9046f7a37ad -0.08 0.43 description +invoice-workspace 0:169240d91658 -0.08 0.21 plan/service +invoice-workspace 0:32e8369a9c4f -0.08 0.14 qty +invoice-workspace 0:e2a9c81da5f6 -0.08 0.24 unitprice(usd) +invoice-workspace 0:5dfb966b2bcf -0.08 0.44 amount(usd) invoice-workspace 0:2bcc555090a1 0.01 0.43 kestrelbusiness+ invoice-workspace 0:68fad867a983 0.06 0.43 workspacesubscription -invoice-workspace 0:e0b844887562 0.06 0.48 business+annual -invoice-workspace 0:84906b0f4b73 0.06 0.39 50users -invoice-workspace 0:5ee31a6284bc 0.06 0.41 8.75 -invoice-workspace 0:843d501d422c 0.06 0.36 437.50 -invoice-workspace 0:3007667b4e18 0.03 0.43 enterprisekeymanagement -invoice-workspace 0:162e9c93c528 0.08 0.43 customer-managedencryptionkeys -invoice-workspace 0:a33a54a73112 0.08 0.47 add-on -invoice-workspace 0:d66c66a96157 0.08 0.42 100.00 -invoice-workspace 0:d66c66a96157#1 0.08 0.36 100.00 -invoice-workspace 0:0036ebf2cfb2 0.03 0.43 prioritysupport -invoice-workspace 0:51833276172f 0.08 0.43 namedengineerandresponsetarget -invoice-workspace 0:fe6d3468cf5c 0.08 0.45 standard -invoice-workspace 0:a99210875f11 0.08 0.36 50.00 -invoice-workspace 0:a99210875f11#1 0.08 0.41 50.00 -invoice-workspace 0:14209e8ccd53 0.03 0.43 workflowautomation -invoice-workspace 0:31be3ff05457 0.08 0.43 templatesandscheduledruns +invoice-workspace 0:e0b844887562 -0.06 0.48 business+annual +invoice-workspace 0:84906b0f4b73 -0.06 0.39 50users +invoice-workspace 0:5ee31a6284bc -0.06 0.41 8.75 +invoice-workspace 0:843d501d422c -0.06 0.36 437.50 +invoice-workspace 0:3007667b4e18 -0.09 0.43 enterprisekeymanagement +invoice-workspace 0:162e9c93c528 -0.04 0.43 customer-managedencryptionkeys +invoice-workspace 0:a33a54a73112 -0.04 0.47 add-on +invoice-workspace 0:d66c66a96157 -0.04 0.42 100.00 +invoice-workspace 0:d66c66a96157#1 -0.04 0.36 100.00 +invoice-workspace 0:0036ebf2cfb2 -0.09 0.43 prioritysupport +invoice-workspace 0:51833276172f -0.04 0.43 namedengineerandresponsetarget +invoice-workspace 0:fe6d3468cf5c -0.04 0.45 standard +invoice-workspace 0:a99210875f11 -0.04 0.36 50.00 +invoice-workspace 0:a99210875f11#1 -0.04 0.41 50.00 +invoice-workspace 0:14209e8ccd53 -0.09 0.43 workflowautomation +invoice-workspace 0:31be3ff05457 -0.04 0.43 templatesandscheduledruns invoice-workspace 0:7f0f70e643bc -0.04 0.41 included invoice-workspace 0:561b2814d3c0 -0.04 0.41 0.00 invoice-workspace 0:561b2814d3c0#1 -0.04 0.34 0.00 invoice-workspace 0:561b2814d3c0#2 -0.03 0.32 0.00 -invoice-workspace 0:3c7ade679fdf 0.35 0.01 paymentdetails -invoice-workspace 0:944d398aea60 0.55 0.07 bankname: -invoice-workspace 0:a18e9fdf120e 0.55 0.00 bayunionbank,n.a. -invoice-workspace 0:0ecb5847ffa7 0.54 0.07 accountname: -invoice-workspace 0:6b4894c28363 0.50 0.07 accountnumber: -invoice-workspace 0:ab92799f9bc7 0.50 0.00 000000123456789 -invoice-workspace 0:c1390f638bd3 0.46 0.07 routing(aba): -invoice-workspace 0:1f873cdde0ca 0.46 0.00 021000021 -invoice-workspace 0:e58256751597 0.42 0.07 swift/bic: -invoice-workspace 0:0fdf54f117f8 0.42 0.00 bayuus33 -invoice-workspace 0:967e0b6ca4b9 0.39 0.07 currency: -invoice-workspace 0:d60fbd8718ec 0.39 0.00 usd -invoice-workspace 0:c608665436db 0.35 0.07 reference: -invoice-workspace 0:3db3fa89ea2c 0.31 0.07 bankaddress: -invoice-workspace 0:b1645851e755 0.31 0.00 1marketplaza,sanfrancisco -invoice-workspace 0:9b600d1211c8 1.18 0.06 pleaseincludetheinvoicenumberiny -invoice-workspace 0:415eb9e42f41 -0.07 0.06 reference. -invoice-workspace 0:d6577e95efba 0.03 0.09 subtotal -invoice-workspace 0:460dd5bae888 0.03 0.39 587.50 +invoice-workspace 0:3c7ade679fdf -0.25 0.01 paymentdetails +invoice-workspace 0:944d398aea60 -0.17 0.07 bankname: +invoice-workspace 0:a18e9fdf120e -0.17 0.00 bayunionbank,n.a. +invoice-workspace 0:0ecb5847ffa7 -0.18 0.07 accountname: +invoice-workspace 0:6b4894c28363 -0.22 0.07 accountnumber: +invoice-workspace 0:ab92799f9bc7 -0.22 0.00 000000123456789 +invoice-workspace 0:c1390f638bd3 -0.26 0.07 routing(aba): +invoice-workspace 0:1f873cdde0ca -0.26 0.00 021000021 +invoice-workspace 0:e58256751597 -0.30 0.07 swift/bic: +invoice-workspace 0:0fdf54f117f8 -0.30 0.00 bayuus33 +invoice-workspace 0:967e0b6ca4b9 -0.33 0.07 currency: +invoice-workspace 0:d60fbd8718ec -0.33 0.00 usd +invoice-workspace 0:c608665436db -0.37 0.07 reference: +invoice-workspace 0:3db3fa89ea2c -0.41 0.07 bankaddress: +invoice-workspace 0:b1645851e755 -0.41 0.00 1marketplaza,sanfrancisco +invoice-workspace 0:9b600d1211c8 0.46 0.06 pleaseincludetheinvoicenumberiny +invoice-workspace 0:415eb9e42f41 -0.79 0.06 reference. +invoice-workspace 0:d6577e95efba -0.09 0.09 subtotal +invoice-workspace 0:460dd5bae888 -0.09 0.39 587.50 invoice-workspace 0:2ee4d3de4ddf -0.03 0.09 tax(0%) -invoice-workspace 0:57a66d21eb1b -0.02 0.09 totaldue -invoice-workspace 0:ad00e93ce79a -0.06 0.64 usd587.50 -invoice-workspace 0:b0553f008513 -0.43 0.15 paymentdueby -invoice-workspace 0:08775a92bfca 0.64 -0.01 thankyouforusingkestrel. -invoice-workspace 0:18e82fbd48a3 0.77 -0.01 questionsaboutthisinvoice?reachu -invoice-workspace 0:3c72ba0e1eb8 0.76 0.06 500howardstreet,6thfloor,sanfran -invoice-workspace 0:9e2917e23527 0.65 -0.10 kestrel.example +invoice-workspace 0:57a66d21eb1b -0.14 0.09 totaldue +invoice-workspace 0:ad00e93ce79a -0.18 0.64 usd587.50 +invoice-workspace 0:b0553f008513 -0.07 0.15 paymentdueby +invoice-workspace 0:08775a92bfca -0.32 -0.01 thankyouforusingkestrel. +invoice-workspace 0:18e82fbd48a3 -0.31 -0.01 questionsaboutthisinvoice?reachu +invoice-workspace 0:3c72ba0e1eb8 -0.32 0.06 500howardstreet,6thfloor,sanfran +invoice-workspace 0:9e2917e23527 -0.31 -0.10 kestrel.example invoice-workspace 0:7b14b8d2c5c4 0.08 -0.16 page1of1 letter-blue_banner 0:8f1010120ed6 0.50 0.04 jordanrivera letter-blue_banner 0:8f1010120ed6#1 0.08 0.00 jordanrivera @@ -3527,15 +3528,15 @@ letter-blue_banner 0:eae27893a255 -0.39 0.00 therestoftheteam. letter-blue_banner 0:a71e98216baa -0.05 0.00 iwouldwelcometheopportunitytobri letter-blue_banner 0:80a6a628ad52 -0.08 0.00 sincerely, letter-boxed_sections 0:8f1010120ed6 0.58 0.22 jordanrivera -letter-boxed_sections 0:8f1010120ed6#1 -0.35 0.00 jordanrivera -letter-boxed_sections 0:8d7a2cca3060 -0.10 0.07 +442055551000|jordan.rivera@exam -letter-boxed_sections 0:bef81b541365 -0.47 0.00 dearhiringteamatnorthwindsystems -letter-boxed_sections 0:ab54410ead82 -0.65 0.00 iamexcitedtosharemyinterestinthe -letter-boxed_sections 0:9185168d2cf8 -0.61 0.00 document-generationsystemsthatba -letter-boxed_sections 0:5fb2802723b6 -0.55 0.00 ienjoytranslatingfuzzyworkflowre -letter-boxed_sections 0:dab2d688b7ab -0.63 0.00 adoptioneasierfortherestofthetea -letter-boxed_sections 0:a71e98216baa -0.33 0.00 iwouldwelcometheopportunitytobri -letter-boxed_sections 0:80a6a628ad52 -0.40 0.00 sincerely, +letter-boxed_sections 0:8f1010120ed6#1 0.37 0.00 jordanrivera +letter-boxed_sections 0:8d7a2cca3060 0.26 0.07 +442055551000|jordan.rivera@exam +letter-boxed_sections 0:bef81b541365 0.25 0.00 dearhiringteamatnorthwindsystems +letter-boxed_sections 0:ab54410ead82 0.07 0.00 iamexcitedtosharemyinterestinthe +letter-boxed_sections 0:9185168d2cf8 0.11 0.00 document-generationsystemsthatba +letter-boxed_sections 0:5fb2802723b6 0.05 0.00 ienjoytranslatingfuzzyworkflowre +letter-boxed_sections 0:dab2d688b7ab 0.09 0.00 adoptioneasierfortherestofthetea +letter-boxed_sections 0:a71e98216baa 0.39 0.00 iwouldwelcometheopportunitytobri +letter-boxed_sections 0:80a6a628ad52 0.32 0.00 sincerely, letter-centered_headline 0:8f1010120ed6 0.16 0.10 jordanrivera letter-centered_headline 0:8f1010120ed6#1 0.00 0.00 jordanrivera letter-centered_headline 0:2d58f0cadc2d 0.15 0.49 platformengineer @@ -3578,20 +3579,20 @@ letter-editorial_blue 0:dda41d31bb3c -0.08 0.00 thatmakeadoptioneasierfortherest letter-editorial_blue 0:a71e98216baa 0.24 0.00 iwouldwelcometheopportunitytobri letter-editorial_blue 0:80a6a628ad52 0.19 0.00 sincerely, letter-engineering_resume 0:8f1010120ed6 -0.04 0.02 jordanrivera -letter-engineering_resume 0:8f1010120ed6#1 -1.36 0.00 jordanrivera +letter-engineering_resume 0:8f1010120ed6#1 -0.04 0.00 jordanrivera letter-engineering_resume 0:2d58f0cadc2d -0.20 0.02 platformengineer letter-engineering_resume 0:fbeea547d99e -0.19 0.19 london,uk letter-engineering_resume 0:89674e6f130e -0.15 0.20 +442055551000 letter-engineering_resume 0:e0f850305ded -0.09 0.09 jordan.rivera@example.com letter-engineering_resume 0:84308bea4540 -0.05 0.96 linkedin letter-engineering_resume 0:c0b0109d9439 -0.13 0.83 github -letter-engineering_resume 0:bef81b541365 -1.39 0.00 dearhiringteamatnorthwindsystems -letter-engineering_resume 0:c5331fbe74e1 -1.63 0.00 iamexcitedtosharemyinterestinthe -letter-engineering_resume 0:f27264b519fd -1.57 0.00 balancepublicapidesign,renderqua -letter-engineering_resume 0:b98ace48a28b -1.57 0.00 ienjoytranslatingfuzzyworkflowre -letter-engineering_resume 0:30edab94d52e -1.51 0.00 oftheteam. -letter-engineering_resume 0:a71e98216baa -1.27 0.00 iwouldwelcometheopportunitytobri -letter-engineering_resume 0:80a6a628ad52 -1.28 0.00 sincerely, +letter-engineering_resume 0:bef81b541365 -0.07 0.00 dearhiringteamatnorthwindsystems +letter-engineering_resume 0:c5331fbe74e1 -0.31 0.00 iamexcitedtosharemyinterestinthe +letter-engineering_resume 0:f27264b519fd -0.25 0.00 balancepublicapidesign,renderqua +letter-engineering_resume 0:b98ace48a28b -0.37 0.00 ienjoytranslatingfuzzyworkflowre +letter-engineering_resume 0:30edab94d52e -0.31 0.00 oftheteam. +letter-engineering_resume 0:a71e98216baa -0.07 0.00 iwouldwelcometheopportunitytobri +letter-engineering_resume 0:80a6a628ad52 -0.08 0.00 sincerely, letter-executive 0:8f1010120ed6 0.12 0.00 jordanrivera letter-executive 0:8f1010120ed6#1 0.02 0.00 jordanrivera letter-executive 0:89ff05847e96 -0.24 0.00 london,uk|+442055551000 @@ -3615,17 +3616,17 @@ letter-mint-editorial-letter 0:dd474e249222 0.22 0.00 makeadoptioneasierforthere letter-mint-editorial-letter 0:a71e98216baa 0.02 0.00 iwouldwelcometheopportunitytobri letter-mint-editorial-letter 0:80a6a628ad52 0.09 0.00 sincerely, letter-modern_professional 0:8f1010120ed6 0.18 0.13 jordanrivera -letter-modern_professional 0:8f1010120ed6#1 -0.12 0.00 jordanrivera +letter-modern_professional 0:8f1010120ed6#1 0.24 0.00 jordanrivera letter-modern_professional 0:89ff05847e96 0.14 0.00 london,uk|+442055551000 letter-modern_professional 0:8817bf9310b6 0.09 0.13 jordan.rivera@example.com|linked -letter-modern_professional 0:bef81b541365 -0.07 0.00 dearhiringteamatnorthwindsystems -letter-modern_professional 0:c65db8c80e17 -0.46 0.00 iamexcitedtosharemyinterestinthe -letter-modern_professional 0:c8d01ef84078 -0.38 0.00 reusabledocument-generationsyste -letter-modern_professional 0:2e5ddee14dbc -0.41 0.00 ienjoytranslatingfuzzyworkflowre -letter-modern_professional 0:906501a5e847 -0.33 0.00 examplesthatmakeadoptioneasierfo -letter-modern_professional 0:7c5a9817c868 -0.48 0.00 iwouldwelcometheopportunitytobri -letter-modern_professional 0:4012eb4b05db -0.28 0.00 group. -letter-modern_professional 0:80a6a628ad52 -0.07 0.00 sincerely, +letter-modern_professional 0:bef81b541365 0.29 0.00 dearhiringteamatnorthwindsystems +letter-modern_professional 0:c65db8c80e17 -0.10 0.00 iamexcitedtosharemyinterestinthe +letter-modern_professional 0:c8d01ef84078 0.10 0.00 reusabledocument-generationsyste +letter-modern_professional 0:2e5ddee14dbc -0.05 0.00 ienjoytranslatingfuzzyworkflowre +letter-modern_professional 0:906501a5e847 0.03 0.00 examplesthatmakeadoptioneasierfo +letter-modern_professional 0:7c5a9817c868 0.00 0.00 iwouldwelcometheopportunitytobri +letter-modern_professional 0:4012eb4b05db 0.08 0.00 group. +letter-modern_professional 0:80a6a628ad52 0.29 0.00 sincerely, letter-monogram_sidebar 0:136c67657614 0.18 0.06 jordan letter-monogram_sidebar 0:8ba35ebe3d5c 0.22 0.12 rivera letter-monogram_sidebar 0:2d58f0cadc2d -0.20 -0.69 platformengineer @@ -3653,11 +3654,11 @@ letter-nordic_clean 0:26e89af4523d -0.35 0.00 ienjoytranslatingfuzzyworkflowre letter-nordic_clean 0:27c5581ffbbc -0.33 0.00 restoftheteam. letter-nordic_clean 0:a71e98216baa -0.10 0.00 iwouldwelcometheopportunitytobri letter-nordic_clean 0:80a6a628ad52 -0.11 0.00 sincerely, -letter-panel 0:8f1010120ed6 0.44 0.25 jordanrivera +letter-panel 0:8f1010120ed6 0.18 0.25 jordanrivera letter-panel 0:8f1010120ed6#1 0.21 0.00 jordanrivera -letter-panel 0:2d58f0cadc2d 0.22 -0.05 platformengineer -letter-panel 0:89ff05847e96 0.20 0.30 london,uk|+442055551000 -letter-panel 0:8817bf9310b6 0.16 0.36 jordan.rivera@example.com|linked +letter-panel 0:2d58f0cadc2d -0.14 -0.05 platformengineer +letter-panel 0:89ff05847e96 -0.16 0.30 london,uk|+442055551000 +letter-panel 0:8817bf9310b6 -0.08 0.36 jordan.rivera@example.com|linked letter-panel 0:bef81b541365 0.06 0.00 dearhiringteamatnorthwindsystems letter-panel 0:ab54410ead82 -0.17 0.00 iamexcitedtosharemyinterestinthe letter-panel 0:9185168d2cf8 -0.17 0.00 document-generationsystemsthatba @@ -3711,43 +3712,43 @@ proposal-editorial 0:53fcd88ebb00 0.38 0.00 cohesivebrandsystemandamodern,co proposal-editorial 0:95bad9757a67 0.33 0.00 outcomewillbeaclear,confidentpre proposal-editorial 0:8863e2b998da 0.40 0.00 improvesengagement,andsupportsyo proposal-editorial 0:f16c2c2f1999 0.49 0.00 projectgoals -proposal-editorial 0:c008ab0ba85f -0.19 0.08 projectduration -proposal-editorial 0:5a6b4bf425f2 -0.37 0.08 6weeks -proposal-editorial 0:7aa73e5c14d3 -0.05 0.08 startwindow -proposal-editorial 0:6fcb2d3f02ba -0.23 0.08 september2026 -proposal-editorial 0:185e8dc84248 -0.03 0.08 primarycontact -proposal-editorial 0:59d00e0c1b99 -0.20 0.08 projectlead -proposal-editorial 0:4190fd3a8d72 0.09 0.08 proposalvalidity -proposal-editorial 0:56a2e019b8aa -0.06 0.08 14days -proposal-editorial 0:265e93f6b9da 0.10 0.08 (until8september2026) -proposal-editorial 0:e2ea93b97611 1.22 0.00 strengthenbrand -proposal-editorial 0:7d95098b921b 0.21 0.00 credibilityandvisual -proposal-editorial 0:218e304f8b84 -0.80 0.00 consistency. -proposal-editorial 0:35597cc9803f 1.22 0.18 improvewebsite -proposal-editorial 0:83f63137756b 0.21 0.18 usabilityanddrive -proposal-editorial 0:cce9fba37d4e -0.80 0.18 meaningfulaction. -proposal-editorial 0:59aaadaf0c54 1.22 0.20 communicateyour -proposal-editorial 0:30193022f687 0.21 0.20 valueclearlyacrossall -proposal-editorial 0:04b5995c746f -0.80 0.20 touchpoints. -proposal-editorial 0:b45d848fe1b6 1.22 0.36 buildascalabledigital -proposal-editorial 0:e8228bfeba0e 0.21 0.36 foundationforfuture -proposal-editorial 0:1fa35c7a1402 -0.80 0.36 growth. -proposal-editorial 0:bc981abcdf59 -0.02 0.00 scopeofwork -proposal-editorial 0:28450edd9a4f -0.31 -0.02 discovery&research -proposal-editorial 0:ce9012b74aa2 0.02 0.04 stakeholderinterviews,brandaudit -proposal-editorial 0:730c3e278933 -0.19 0.04 audienceinsightstoinformstrategy -proposal-editorial 0:12bff3036b66 -0.12 -0.02 visualidentityrefinement -proposal-editorial 0:937ad523a90c 0.09 0.04 refinelogosystem,colorpalette,ty -proposal-editorial 0:9b232e66f46c -0.15 0.04 guidelinesforacohesive,modernide -proposal-editorial 0:fc5134bf5fd1 -0.08 -0.02 websiteux/uidesign -proposal-editorial 0:5d58b01c7096 0.25 0.04 designaresponsive,accessibility- -proposal-editorial 0:5d6068f6a879 -0.11 0.04 navigationandclearconversionpath -proposal-editorial 0:32001e20b2ed 0.08 -0.02 contentstructure&messaging -proposal-editorial 0:b3c948ec3e36 0.29 0.04 definesitearchitecture,keymessag -proposal-editorial 0:231428fde7aa 0.05 0.04 communicatevalueandbuildtrust. -proposal-editorial 0:8c7703bb6fb7 0.12 -0.02 launchsupport -proposal-editorial 0:34f9fe468474 0.45 0.04 developerhandoff,qasupport,train -proposal-editorial 0:2b4cf15f6f16 0.09 0.04 toensureasmoothlaunch. +proposal-editorial 0:c008ab0ba85f 0.17 0.08 projectduration +proposal-editorial 0:5a6b4bf425f2 -0.01 0.08 6weeks +proposal-editorial 0:7aa73e5c14d3 0.31 0.08 startwindow +proposal-editorial 0:6fcb2d3f02ba 0.13 0.08 september2026 +proposal-editorial 0:185e8dc84248 0.33 0.08 primarycontact +proposal-editorial 0:59d00e0c1b99 0.16 0.08 projectlead +proposal-editorial 0:4190fd3a8d72 0.33 0.08 proposalvalidity +proposal-editorial 0:56a2e019b8aa 0.18 0.08 14days +proposal-editorial 0:265e93f6b9da 0.34 0.08 (until8september2026) +proposal-editorial 0:e2ea93b97611 1.94 0.00 strengthenbrand +proposal-editorial 0:7d95098b921b 0.93 0.00 credibilityandvisual +proposal-editorial 0:218e304f8b84 -0.08 0.00 consistency. +proposal-editorial 0:35597cc9803f 1.94 0.18 improvewebsite +proposal-editorial 0:83f63137756b 0.93 0.18 usabilityanddrive +proposal-editorial 0:cce9fba37d4e -0.08 0.18 meaningfulaction. +proposal-editorial 0:59aaadaf0c54 1.94 0.20 communicateyour +proposal-editorial 0:30193022f687 0.93 0.20 valueclearlyacrossall +proposal-editorial 0:04b5995c746f -0.08 0.20 touchpoints. +proposal-editorial 0:b45d848fe1b6 1.94 0.36 buildascalabledigital +proposal-editorial 0:e8228bfeba0e 0.93 0.36 foundationforfuture +proposal-editorial 0:1fa35c7a1402 -0.08 0.36 growth. +proposal-editorial 0:bc981abcdf59 0.70 0.00 scopeofwork +proposal-editorial 0:28450edd9a4f 0.41 -0.02 discovery&research +proposal-editorial 0:ce9012b74aa2 0.74 0.04 stakeholderinterviews,brandaudit +proposal-editorial 0:730c3e278933 0.53 0.04 audienceinsightstoinformstrategy +proposal-editorial 0:12bff3036b66 0.60 -0.02 visualidentityrefinement +proposal-editorial 0:937ad523a90c 0.81 0.04 refinelogosystem,colorpalette,ty +proposal-editorial 0:9b232e66f46c 0.57 0.04 guidelinesforacohesive,modernide +proposal-editorial 0:fc5134bf5fd1 0.64 -0.02 websiteux/uidesign +proposal-editorial 0:5d58b01c7096 0.97 0.04 designaresponsive,accessibility- +proposal-editorial 0:5d6068f6a879 0.61 0.04 navigationandclearconversionpath +proposal-editorial 0:32001e20b2ed 0.68 -0.02 contentstructure&messaging +proposal-editorial 0:b3c948ec3e36 1.01 0.04 definesitearchitecture,keymessag +proposal-editorial 0:231428fde7aa 0.77 0.04 communicatevalueandbuildtrust. +proposal-editorial 0:8c7703bb6fb7 0.84 -0.02 launchsupport +proposal-editorial 0:34f9fe468474 1.05 0.04 developerhandoff,qasupport,train +proposal-editorial 0:2b4cf15f6f16 0.81 0.04 toensureasmoothlaunch. proposal-editorial 0:026890c58de9 0.12 0.00 northlinestudio|northlinestudio. proposal-editorial 1:5205c2a261bc 0.41 0.02 northline proposal-editorial 1:da0daaba4b15 0.32 0.02 studio @@ -3817,11 +3818,11 @@ proposal-editorial 1:5130aeada3db 0.67 0.08 majordeliverable. proposal-editorial 1:06ebb5670fa8 0.40 0.60 ownershipofallfinaldeliverables proposal-editorial 1:deda6d86d965 0.79 0.08 transferstoasterahealthco.after proposal-editorial 1:aaa7d3e9affb 0.32 0.08 fullpaymentisreceived. -proposal-editorial 1:c1514c6cdad1 1.30 0.00 acceptance -proposal-editorial 1:893663b06769 0.94 0.00 bysigningbelow,youagreetothescop -proposal-editorial 1:df16232de5b9 0.97 0.00 acceptedby: -proposal-editorial 1:f089d24d7cf3 0.97 -0.01 signature: -proposal-editorial 1:c74c9cd82f13 0.97 -0.19 date: +proposal-editorial 1:c1514c6cdad1 1.66 0.00 acceptance +proposal-editorial 1:893663b06769 1.30 0.00 bysigningbelow,youagreetothescop +proposal-editorial 1:df16232de5b9 1.33 0.00 acceptedby: +proposal-editorial 1:f089d24d7cf3 1.33 -0.01 signature: +proposal-editorial 1:c74c9cd82f13 1.33 -0.19 date: proposal-editorial 1:026890c58de9 0.12 0.00 northlinestudio|northlinestudio. proposal-indigo 0:07f15cde5b18 0.22 -0.07 kestrel proposal-indigo 0:ecd1378bc9dc 0.18 -0.46 proposal @@ -3896,47 +3897,47 @@ proposal-indigo 0:29208032c874 0.77 -0.01 kestrel.example/business|busines proposal-modern 0:ecd1378bc9dc 0.18 0.00 proposal proposal-modern 0:f592a683c61d 0.31 0.00 documentplatformconsolidation proposal-modern 0:bbe07492ee1f 0.28 0.00 proposalgc-p-2026-014prepared02a -proposal-modern 0:566835ed7fba 0.01 -0.04 executivesummary -proposal-modern 0:7ccf0e6c59fa -0.13 -0.04 aphasedengagementtoretireper-tea -proposal-modern 0:75857a458999 -0.42 -0.04 from -proposal-modern 0:c26c22b94338 -0.48 -0.04 graphcomposestudio -proposal-modern 0:2a08ce5567fb -0.65 -0.04 18layoutstreet -proposal-modern 0:fbeea547d99e -0.73 -0.04 london,uk -proposal-modern 0:3c8401edb4cc -0.80 -0.04 hello@graphcompose.dev -proposal-modern 0:89674e6f130e -0.76 -0.04 +442055551000 -proposal-modern 0:213a61c7aeb6 -0.80 -0.04 graphcompose.dev -proposal-modern 0:f890faef907f -0.48 0.01 northwindsystems -proposal-modern 0:577a7fcdaa02 -0.65 0.01 attn:procurement -proposal-modern 0:91eefd794f79 -0.73 0.01 410marketavenue -proposal-modern 0:3daace874084 -0.80 0.01 procurement@northwind.example -proposal-modern 0:5f161c914988 -0.41 -0.04 scope -proposal-modern 0:9e580657f485 -0.50 -0.04 discovery,architecture,andarefer -proposal-modern 0:cec9111de36d -0.35 -0.04 approach -proposal-modern 0:3215ea3be6d9 -0.56 -0.04 iterativedeliverywithweeklycheck -proposal-modern 0:94d192b3a326 -0.41 -0.04 timeline -proposal-modern 0:02195b8e9896 -0.46 0.00 phase -proposal-modern 0:caa79af4db67 -0.46 0.06 duration -proposal-modern 0:41ffd8b76afc -0.46 0.01 details -proposal-modern 0:fa44132b238e -0.53 0.04 discovery -proposal-modern 0:fa44132b238e#1 -0.41 0.04 discovery -proposal-modern 0:b183847fe9f8 -0.53 -0.02 2weeks -proposal-modern 0:4b20bfb69ca7 -0.53 0.05 stakeholderinterviews+audit -proposal-modern 0:44575cf5b285 -0.48 0.04 build -proposal-modern 0:44575cf5b285#1 -0.48 0.04 build -proposal-modern 0:5a6b4bf425f2 -0.48 -0.02 6weeks -proposal-modern 0:7a802048127d -0.48 0.05 engine+templatemigration -proposal-modern 0:f9b21c4bda58 -0.39 -0.04 investment -proposal-modern 0:4a33eacd5fa6 -0.44 0.00 item -proposal-modern 0:c9046f7a37ad -0.44 0.06 description -proposal-modern 0:cf38d95c9c6b -0.44 1.12 amount -proposal-modern 0:fe9b6b4f133b -0.41 -0.02 workshops+auditgbp6,000 -proposal-modern 0:62e788ae3916 -0.48 -0.02 engine+templatesgbp24,000 -proposal-modern 0:11239872d178 -0.48 0.00 total -proposal-modern 0:1c3065490625 -0.48 1.12 gbp30,000 -proposal-modern 0:63feb7230a5d -0.37 -0.04 acceptanceterms -proposal-modern 0:35046a9f5675 -0.46 0.00 •50%onsignature,50%ondelivery. -proposal-modern 0:f03c1877ea2b -0.45 0.00 •validfor30daysfromthepreparedda -proposal-modern 0:90572e911376 -0.41 -0.04 thankyouforconsideringgraphcompo +proposal-modern 0:566835ed7fba 0.25 -0.04 executivesummary +proposal-modern 0:7ccf0e6c59fa 0.23 -0.04 aphasedengagementtoretireper-tea +proposal-modern 0:75857a458999 0.30 -0.04 from +proposal-modern 0:c26c22b94338 0.24 -0.04 graphcomposestudio +proposal-modern 0:2a08ce5567fb -0.05 -0.04 18layoutstreet +proposal-modern 0:fbeea547d99e -0.13 -0.04 london,uk +proposal-modern 0:3c8401edb4cc -0.08 -0.04 hello@graphcompose.dev +proposal-modern 0:89674e6f130e -0.13 -0.04 +442055551000 +proposal-modern 0:213a61c7aeb6 -0.20 -0.04 graphcompose.dev +proposal-modern 0:f890faef907f 0.24 0.01 northwindsystems +proposal-modern 0:577a7fcdaa02 -0.05 0.01 attn:procurement +proposal-modern 0:91eefd794f79 -0.13 0.01 410marketavenue +proposal-modern 0:3daace874084 -0.08 0.01 procurement@northwind.example +proposal-modern 0:5f161c914988 0.31 -0.04 scope +proposal-modern 0:9e580657f485 0.10 -0.04 discovery,architecture,andarefer +proposal-modern 0:cec9111de36d 0.25 -0.04 approach +proposal-modern 0:3215ea3be6d9 0.16 -0.04 iterativedeliverywithweeklycheck +proposal-modern 0:94d192b3a326 0.31 -0.04 timeline +proposal-modern 0:02195b8e9896 0.14 0.00 phase +proposal-modern 0:caa79af4db67 0.14 0.06 duration +proposal-modern 0:41ffd8b76afc 0.14 0.01 details +proposal-modern 0:fa44132b238e 0.19 0.04 discovery +proposal-modern 0:fa44132b238e#1 0.19 0.04 discovery +proposal-modern 0:b183847fe9f8 0.19 -0.02 2weeks +proposal-modern 0:4b20bfb69ca7 0.19 0.05 stakeholderinterviews+audit +proposal-modern 0:44575cf5b285 0.24 0.04 build +proposal-modern 0:44575cf5b285#1 0.24 0.04 build +proposal-modern 0:5a6b4bf425f2 0.24 -0.02 6weeks +proposal-modern 0:7a802048127d 0.24 0.05 engine+templatemigration +proposal-modern 0:f9b21c4bda58 0.33 -0.04 investment +proposal-modern 0:4a33eacd5fa6 0.16 0.00 item +proposal-modern 0:c9046f7a37ad 0.16 0.06 description +proposal-modern 0:cf38d95c9c6b 0.16 1.12 amount +proposal-modern 0:fe9b6b4f133b 0.19 -0.02 workshops+auditgbp6,000 +proposal-modern 0:62e788ae3916 0.24 -0.02 engine+templatesgbp24,000 +proposal-modern 0:11239872d178 0.12 0.00 total +proposal-modern 0:1c3065490625 0.12 1.12 gbp30,000 +proposal-modern 0:63feb7230a5d 0.35 -0.04 acceptanceterms +proposal-modern 0:35046a9f5675 0.26 0.00 •50%onsignature,50%ondelivery. +proposal-modern 0:f03c1877ea2b 0.27 0.00 •validfor30daysfromthepreparedda +proposal-modern 0:90572e911376 0.19 -0.04 thankyouforconsideringgraphcompo proposal-northline 0:5205c2a261bc -0.43 0.04 northline proposal-northline 0:da0daaba4b15 -0.43 0.04 studio proposal-northline 0:ecd1378bc9dc -0.34 0.21 proposal @@ -4063,11 +4064,11 @@ proposal-northline 1:566f68df6dd8 0.14 0.10 finalpayment. proposal-northline 1:06ebb5670fa8 0.49 0.62 ownershipofallfinaldeliverables proposal-northline 1:5312201597c1 0.78 0.10 transferstoasterahealthco.afterf proposal-northline 1:d31e8d77a816 0.30 0.10 paymentisreceived. -proposal-northline 1:c1514c6cdad1 0.25 0.12 acceptance -proposal-northline 1:893663b06769 0.52 0.04 bysigningbelow,youagreetothescop -proposal-northline 1:df16232de5b9 0.50 0.04 acceptedby: -proposal-northline 1:f089d24d7cf3 0.50 0.08 signature: -proposal-northline 1:c74c9cd82f13 0.50 0.09 date: +proposal-northline 1:c1514c6cdad1 0.61 0.12 acceptance +proposal-northline 1:893663b06769 0.88 0.04 bysigningbelow,youagreetothescop +proposal-northline 1:df16232de5b9 0.86 0.04 acceptedby: +proposal-northline 1:f089d24d7cf3 0.86 0.08 signature: +proposal-northline 1:c74c9cd82f13 0.86 0.09 date: proposal-northline 1:026890c58de9 0.10 0.00 northlinestudio|northlinestudio. receipt-modern 0:2b019b5b46da 0.29 -0.04 northwindpay receipt-modern 0:a3c304a23bb1 0.23 0.00 transferconfirmation diff --git a/qa/src/test/resources/docx-fidelity/word-windows.tsv b/qa/src/test/resources/docx-fidelity/word-windows.tsv index 7dcce56e3..e759091a3 100644 --- a/qa/src/test/resources/docx-fidelity/word-windows.tsv +++ b/qa/src/test/resources/docx-fidelity/word-windows.tsv @@ -1,64 +1,64 @@ # word 16.0 (16.0.20430) on windows document engine_pages editor_pages lines matched median p90 over2 cv-blue_banner 2 2 54 52 0.14 0.49 0 -cv-boxed_sections 2 2 58 58 0.29 0.54 0 +cv-boxed_sections 2 2 58 58 0.28 0.45 0 cv-centered_headline 2 2 58 56 0.11 0.26 0 -cv-charcoal_gold 1 1 85 83 0.13 0.44 0 -cv-classic_serif 2 2 57 54 0.17 0.25 0 -cv-compact_mono 1 1 58 58 0.34 0.91 0 +cv-charcoal_gold 1 1 85 83 0.18 0.27 0 +cv-classic_serif 2 2 57 54 0.31 0.44 0 +cv-compact_mono 1 1 58 58 0.24 0.91 0 cv-editorial_blue 2 2 82 82 0.14 0.27 0 -cv-engineering_resume 1 1 57 57 0.58 1.54 0 +cv-engineering_resume 1 1 57 57 0.24 0.42 0 cv-executive 2 2 60 60 0.21 0.43 0 cv-midnight_navy 1 1 86 84 0.22 0.82 0 -cv-minimal_underlined 2 2 59 59 0.71 1.23 0 +cv-minimal_underlined 2 2 59 59 0.44 0.70 0 cv-mint_editorial 2 2 59 59 0.13 0.31 0 -cv-modern_professional 2 2 61 59 0.09 0.35 0 +cv-modern_professional 2 2 61 59 0.32 0.44 0 cv-monogram_sidebar 1 1 53 50 0.28 0.67 0 cv-navy_sidebar 1 1 71 69 0.13 0.36 0 -cv-nordic_clean 1 1 63 58 0.22 0.61 0 +cv-nordic_clean 1 1 63 58 0.23 0.49 0 cv-orange_ops 1 1 108 106 0.29 0.71 0 -cv-panel 1 1 79 74 0.34 0.67 0 +cv-panel 1 1 79 74 0.83 1.30 0 cv-professional_sidebar 1 1 68 64 0.30 0.49 0 cv-serif_headline 1 1 103 103 0.50 1.03 0 cv-sidebar_portrait 1 1 49 49 0.15 0.29 0 cv-slate_orange 1 1 87 85 0.48 1.17 0 cv-teal_pulse 1 1 57 57 0.11 0.38 0 cv-terracotta_rail 1 1 102 102 0.42 0.87 0 -cv-timeline_minimal 2 2 89 86 0.36 0.48 0 -cv-violet_grid 1 1 80 78 0.23 0.37 0 +cv-timeline_minimal 2 2 89 87 0.36 0.47 0 +cv-violet_grid 1 1 80 78 0.23 0.42 0 invoice-classic 1 1 56 56 0.22 0.36 0 invoice-classic_long 2 2 166 166 0.27 0.34 0 invoice-consulting 1 1 92 92 0.70 1.02 0 invoice-consulting_long 2 2 236 236 0.74 0.97 0 invoice-luma_studio 1 1 97 97 0.13 0.42 0 invoice-luma_studio_long 3 3 192 192 0.22 0.38 0 -invoice-merchant 1 1 94 94 0.14 0.35 0 -invoice-metered 1 1 99 99 0.14 0.58 0 +invoice-merchant 1 1 94 94 0.13 0.25 0 +invoice-metered 1 1 99 99 0.14 0.57 0 invoice-modern 1 1 54 54 0.09 0.22 0 invoice-modern_long 2 2 162 162 0.23 0.31 0 -invoice-obsidian 1 1 81 81 0.32 0.78 0 -invoice-payments 1 1 104 104 0.15 0.28 0 +invoice-obsidian 1 1 81 81 0.28 0.76 0 +invoice-payments 1 1 104 104 0.09 0.20 0 invoice-platform 1 1 111 111 0.19 0.41 0 -invoice-subscription 1 1 81 81 0.23 0.64 0 -invoice-workspace 1 1 90 90 0.12 0.54 0 +invoice-subscription 1 1 81 81 0.69 0.97 0 +invoice-workspace 1 1 90 90 0.14 0.32 0 letter-blue_banner 1 1 10 10 0.39 0.50 0 -letter-boxed_sections 1 1 10 10 0.55 0.63 0 +letter-boxed_sections 1 1 10 10 0.26 0.39 0 letter-centered_headline 1 1 11 11 0.03 0.19 0 letter-classic_serif 1 1 10 10 0.13 0.17 0 letter-compact_mono 1 1 10 8 0.28 0.35 0 letter-editorial_blue 1 1 12 12 0.19 0.26 0 -letter-engineering_resume 1 1 15 15 1.27 1.57 0 +letter-engineering_resume 1 1 15 15 0.13 0.31 0 letter-executive 1 1 12 12 0.12 0.24 0 letter-mint-editorial-letter 1 1 10 10 0.18 0.32 0 -letter-modern_professional 1 1 12 12 0.28 0.46 0 +letter-modern_professional 1 1 12 12 0.10 0.29 0 letter-monogram_sidebar 1 1 12 12 0.14 0.20 0 letter-nordic_clean 1 1 15 15 0.16 0.35 0 -letter-panel 1 1 13 13 0.17 0.25 0 +letter-panel 1 1 13 13 0.16 0.21 0 letter-sidebar_portrait 1 1 12 12 0.41 0.52 0 letter-timeline_minimal 1 1 15 15 0.29 0.53 0 -proposal-editorial 2 2 132 130 0.41 0.97 0 +proposal-editorial 2 2 132 130 0.57 1.08 0 proposal-indigo 1 1 72 70 0.40 0.62 0 -proposal-modern 1 1 44 44 0.48 0.73 0 -proposal-northline 2 2 132 132 0.27 0.67 0 +proposal-modern 1 1 44 44 0.19 0.31 0 +proposal-northline 2 2 132 132 0.27 0.71 0 receipt-modern 1 1 57 57 0.33 0.43 0 rota-cobalt 1 1 154 154 0.32 0.99 0 diff --git a/render-docx/README.md b/render-docx/README.md index 08c5e7245..023629229 100644 --- a/render-docx/README.md +++ b/render-docx/README.md @@ -116,8 +116,8 @@ What is not written — each one is named in the export report column measures the space round it to its text, with a padding below zero or a column hanging into it, or with a margin below zero above or below it or at a side in a cell, named in the export report as `row paint`. Elsewhere a row that paints is written as a panel holding - its columns, its borders above and below named where Word draws them outside the panel's - row, and its columns where its padding does not take its top border. + its columns, what of its borders above and below Word draws past its box taken by the space + round it and its padding, and named where neither takes it. - **Translucency where Word holds an opaque colour only** — a cell's shading, a border, a rule, a chip's run shading: the colour is flattened against what Word paints under it — the panel or cell the export shaded, or what the page paints there — and a text header's separator against diff --git a/render-docx/src/main/java/com/demcha/compose/document/backend/semantic/docx/DocxSemanticBackend.java b/render-docx/src/main/java/com/demcha/compose/document/backend/semantic/docx/DocxSemanticBackend.java index 61684c74c..e6fc21677 100644 --- a/render-docx/src/main/java/com/demcha/compose/document/backend/semantic/docx/DocxSemanticBackend.java +++ b/render-docx/src/main/java/com/demcha/compose/document/backend/semantic/docx/DocxSemanticBackend.java @@ -248,9 +248,15 @@ public final class DocxSemanticBackend implements SemanticBackend { private double hangingOverBy; // How far the last line of the cell written last hangs below everything the cell writes // under it, in points: Word's cell is that much taller than its content on the page (see - // writeInCell). A row reads it for each of its cells (writeRow); a panel or a stack written - // as columns does not, and that much still makes its table taller. + // writeInCell). A row reads it for each of its cells (writeRow), and a panel for its own + // (writePanelPiece); a stack written as columns does not, and that much still makes its + // table taller. private double cellOverhang; + // The border below a panel that the space above the paragraph hangingOver opens did not take, + // in points, named with what that paragraph's own top edge leaves of the hang, on the node + // the paragraph is written for (nameTheTailNotTaken). + private double borderNotTakenOver; + private DocumentNode tailOverNode; /** * The tables whose first row text stands above, by cell — see {@link #standsAboveItsCell}. @@ -426,6 +432,13 @@ public final class DocxSemanticBackend implements SemanticBackend { */ private double borderBelow; + /** + * The cell of the panel whose border {@link #borderBelow} is, whose padding below takes what + * of it the space below does not ({@link #nameTheTailNotTaken}); {@code null} where it is a + * row's, carried out of a cell, which no one cell's padding decides. + */ + private XWPFTableCell borderBelowCell; + /** The page's height in points, or {@code NaN} when the export has no canvas. */ private double canvasHeight = Double.NaN; @@ -840,6 +853,8 @@ private byte[] write(List sections, Path outputFile) throws Exc } writeNode(document, roots.get(root)); } + // A hang the last paragraph was to take out of its own top edge and never did. + nameAHangLeftOver(); raiseRows(); // The paragraph closing a section that ends with a table is also the one that // carries the drawings nothing else on the last page carried. @@ -5010,6 +5025,10 @@ private void writePanel(XWPFDocument document, DocumentNode node, ContainerPaint for (int index = 0; index < pieces.size(); index++) { if (index > 0) { writePageBreak(document); + } else if (currentCell == null && startsAPageOfItsOwn(node)) { + // What the block above leaves below itself stays on its page, as above a table + // the layout moves to a new page (writeTableWithItsOwnSpacing). + leaveThePageAbove(); } List piece = pieces.get(index); writePanelPiece(document, node, paint, () -> writeChildren(document, piece, spacingOf(node)), @@ -5044,14 +5063,18 @@ private void writePanelPiece(XWPFDocument document, DocumentNode node, Container owePendingSpacingAfter(carriedSpacingBefore + (first ? margin.top() : 0)); carriedSpacingBefore = 0; double topNotTaken = 0; + // A shape's layers are centred in it, and its outline holds its height whole, its borders + // drawn inside it (holdThePanelsHeight): nothing of it reaches past its box. + boolean heldWhole = node instanceof ShapeContainerNode; if (first) { - // Word draws a row's top and bottom borders outside its shading, so the table is as - // much taller than the panel as its borders are thick. The page strokes them on the - // box's edge, taking no room. So the border comes out of the space above, and so - // does the one a panel just above could not take out of its own space below. - topNotTaken = Math.max(0, strokeWidth(borders.top()) - Math.max(0, pendingSpacingAfter - borderBelow)); - pendingSpacingAfter = Math.max(0, pendingSpacingAfter - strokeWidth(borders.top()) - borderBelow); - borderBelow = 0; + // Word draws a panel's top and bottom borders past its box where the page strokes them + // on the box's edge, taking no room (outsideTheRow). The space above takes the reach + // of the top one, after what the block above leaves below itself, which the table + // takes and names with the rest of its tail (newTable). + double reach = heldWhole ? 0 : outsideTheRow(borders.top(), padding.top()); + double taken = Math.min(reach, Math.max(0, pendingSpacingAfter - hangingBelow - borderBelow)); + topNotTaken = reach - taken; + pendingSpacingAfter -= taken; } if (onANewPage) { holdTheSpaceAboveOnItsPage(document); @@ -5160,39 +5183,33 @@ private void writePanelPiece(XWPFDocument document, DocumentNode node, Container // line of text taller. holdToHairline(cell.addParagraph()); } - // Word starts the cell's content below its top border, or its top margin where that is - // wider, the border then standing inside the margin; the page starts it the padding below - // the panel's edge. What of the border no space above took, less the padding, is how far - // low the content would stand: a padding as wide as the border holds it. - double low = topNotTaken - padding.top(); - takeTheTopBorderInside(cell, low); - // Where its padding does not hold its top border, Word draws both borders outside the - // row's height, the panel's top where the space above put it: so the height held is the - // page's less the part of the top border no space above took and less the bottom border. - // holdRowAtLeast already takes the heavier of the two off; the rest comes off here. A - // padding that holds the border leaves the height as it was: Word draws the border inside - // the margin, and InvoiceMetered's card moved its top down taking it off. - double bordersOutside = low > 0 - ? Math.max(0, topNotTaken + strokeWidth(borders.bottom()) - - Math.max(strokeWidth(borders.top()), strokeWidth(borders.bottom()))) - : 0; + // What of the border's reach the space above did not take stands the content that low: + // its padding takes what it can of that, then the space above its first paragraph. The + // border is then drawn that much inside the panel's edge, the content where the page + // sets it. + double low = topNotTaken; + double fromThePadding = takeOffTheCellMargin(cell, true, low); + // Taken off the content, it comes off the content's height held too (holdThePanelsHeight). + double fromTheContent = takeTheTopBorderInside(cell, Math.max(0, low - fromThePadding)); + double unheld = low - fromThePadding - fromTheContent; + if (unheld > TAIL_CLEARANCE) { + report.add(DocxExportReport.Severity.APPROXIMATED, node.nodeKind(), layout.pathOf(node), + "its content stands " + pointsOf(unheld) + "pt lower than the page sets it, and what follows " + + "up to as much: Word sets it below the whole of its top border, and neither the space above it " + + "nor its padding takes what of the border reaches past the panel's box"); + } com.demcha.compose.document.layout.PlacedNode placed = first && last && layout.onOnePage(node) ? layout.placement(node) : null; if (placed != null && placed.placementHeight() > 0) { // Its height is the page's: what makes a panel taller than its text — an icon drawn // where the page puts it, a fixed outline — is not in the cell. MerchantInvoice's // due-date card closed from 59.4pt to its text's 26, and its calendar hung below it. - // Measured on MerchantInvoice's payment panel, Word drew it 0.8pt taller than the page - // without the borders outside taken off, and as tall with them; LibreOffice, whose - // height there its content sets, draws it that border's width shorter. - holdRowAtLeast(table.getRow(0), placed.placementHeight() - bordersOutside); + holdThePanelsHeight(table.getRow(0), placed.placementHeight() - fromTheContent, padding, borders, heldWhole); } else if (first && last && layout.placement(node) == null && node instanceof ShapeContainerNode shape && shape.outline().height() > 0) { // Composed in a table cell, it has no placement; its outline states its height, as it // states its width (panelWidth). CobaltRota's shift chips, 17.5pt outlines round a - // line of text, closed to the text's 12.7pt in Word. Less the borders drawn outside: - // its outlined chips, 9.2pt outlines with a 1.125pt border, stood 10.3pt tall in Word - // and 10.2pt in LibreOffice, each row holding one 1.1pt taller than the page's. - holdRowAtLeast(table.getRow(0), shape.outline().height() - bordersOutside); + // line of text, closed to the text's 12.7pt in Word. + holdThePanelsHeight(table.getRow(0), shape.outline().height(), padding, borders, true); } // In the body it is written even when it is 0. The indent places the cell's text, and @@ -5210,9 +5227,95 @@ private void writePanelPiece(XWPFDocument document, DocumentNode node, Container tableIndent.setW(BigInteger.valueOf(Math.round(indent * POINT_TO_TWIP))); } if (last) { - double below = strokeWidth(borders.bottom()); - owePendingSpacingAfter(Math.max(0, margin.bottom() - below)); - borderBelow = Math.max(0, below - margin.bottom()); + // What the content leaves below itself in Word past where the page ends it — a last + // line hanging past it, a card's border below carried out of the cell — makes Word's + // panel that much taller. The room the page leaves under the content in a panel it + // holds taller takes it first; then the padding below, the line hanging into it as on + // the page; what follows takes the rest out of the space between them, as below a row + // (writeRow). A shape's layers are centred in the height it holds, which takes it. + double roomUnder = heldWhole ? Double.POSITIVE_INFINITY : roomUnderItsContent(node, placed, padding); + double hang = Math.max(0, cellOverhang - roomUnder); + double carried = Math.max(0, borderBelow - Math.max(0, roomUnder - cellOverhang)); + double fromThePaddingBelow = takeOffTheCellMargin(cell, false, hang + carried); + hangingBelow = Math.max(hangingBelow, hang - fromThePaddingBelow); + carried = Math.max(0, carried - Math.max(0, fromThePaddingBelow - hang)); + // Its own border below reaches past its box as well, and a margin below zero pulls what + // follows up, as a paragraph's does: neither is the other. + double reach = (heldWhole ? 0 : outsideTheRow(borders.bottom(), padding.bottom())) + carried; + double outside = Math.max(0, margin.bottom()); + owePendingSpacingAfter(outside - reach); + borderBelow = Math.max(0, reach - outside); + if (margin.bottom() < 0) { + pullBelow -= margin.bottom(); + } + // What of the border the space below does not take, the padding left takes, at the + // border's place (nameTheTailNotTaken). + borderBelowCell = cell; + } + cellOverhang = 0; + } + + /** + * How much room the page leaves under a panel's content, above its padding, in points: what + * the panel's height holds below its lowest child, beyond that child's own margin. 0 where the + * panel's height is not held ({@link #holdThePanelsHeight}) or the layout does not say. + */ + private double roomUnderItsContent(DocumentNode node, com.demcha.compose.document.layout.PlacedNode placed, + DocumentInsets padding) { + if (placed == null || node.children().isEmpty()) { + return 0; + } + double lowest = Double.POSITIVE_INFINITY; + for (DocumentNode child : node.children()) { + com.demcha.compose.document.layout.PlacedNode at = layout.placement(child); + if (at == null || at.startPage() != placed.startPage() || at.endPage() != placed.endPage()) { + return 0; + } + lowest = Math.min(lowest, at.placementY() - Math.max(0, child.margin().bottom())); + } + return Math.max(0, lowest - placed.placementY() - Math.max(0, padding.bottom())); + } + + /** + * Takes up to {@code points} off a cell's top or bottom margin, as far as the margin holds. + * + * @return the points taken + */ + private static double takeOffTheCellMargin(XWPFTableCell cell, boolean top, double points) { + long held = cellMargin(cell, top); + long taken = Math.min(held, toTwips(points)); + if (taken > 0) { + setCellMarginTwips(cell, top, held - taken); + } + return Math.max(0, taken) / POINT_TO_TWIP; + } + + /** + * Holds a panel's row to the height the page gives the panel. + * + *

Word and LibreOffice read a row's written height as its content's, and a panel's row is + * that, its margins and both its borders tall: measured, an outlined card padded 4pt round a + * 12pt line, held a point above its content's height, stood a point taller in both than the + * page's. So a panel set from the top holds the page's height less its padding, its margins + * and borders coming round its content where the space round it and its padding take them + * ({@link #outsideTheRow}). A shape container, its layers centred in it, holds its outline's + * height whole, its margins and borders off its content, as the page draws them + * inside its outline: CobaltRota's outlined chips, 9.2pt outlines with a 1.125pt border, stood + * 10.3pt tall in Word and 10.2pt in LibreOffice with neither border taken off.

+ * + * @param whole whether the height is the panel's outline, its borders inside it + */ + private static void holdThePanelsHeight(XWPFTableRow row, double height, DocumentInsets padding, + DocumentBorders borders, boolean whole) { + if (whole) { + // holdRowAtLeast takes the margins and the heavier border off; the lighter one too. + holdRowAtLeast(row, height - Math.min(strokeWidth(borders.top()), strokeWidth(borders.bottom()))); + return; + } + long twips = toTwips(height - Math.max(0, padding.top()) - Math.max(0, padding.bottom())); + if (twips > 0) { + row.setHeight((int) twips); + row.setHeightRule(org.apache.poi.xwpf.usermodel.TableRowHeightRule.AT_LEAST); } } @@ -5220,23 +5323,24 @@ private void writePanelPiece(XWPFDocument document, DocumentNode node, Container * Takes how far a panel's content would stand low in Word out of the space above its first * paragraph, as far as that holds. * - *

Word draws a cell's top border above its content unless the cell's top margin is wider; - * the page strokes it on the panel's edge. Where the panel has no padding to hold the border - * and less space above it than the border — it opens a cell, or follows nothing — every line - * inside stood the border's width low: {@code MerchantInvoice}'s payment panel, first in its + *

Word sets a cell's content below its whole top border and its margin; the page strokes + * the border on the panel's edge ({@link #outsideTheRow}). Where neither the space above the + * panel nor its padding takes what of the border reaches past its box — it opens a cell, or + * follows nothing — every line inside stood that much low: {@code MerchantInvoice}'s payment panel, first in its * row's cell, stood 0.9pt low in Word and pushed its footer onto a second page. The space above * its first paragraph — the room the page leaves over its heading — takes it instead.

* * @param low how far low the content would stand, in points + * @return how much of it the space above the first paragraph took, in points */ - private static void takeTheTopBorderInside(XWPFTableCell cell, double low) { + private static double takeTheTopBorderInside(XWPFTableCell cell, double low) { if (!(low > 0) || cell.getBodyElements().isEmpty() || !(cell.getBodyElements().get(0) instanceof XWPFParagraph first)) { - return; + return 0; } CTPPr properties = first.getCTP().getPPr(); if (properties == null || !properties.isSetSpacing() || !properties.getSpacing().isSetBefore()) { - return; + return 0; } CTSpacing spacing = properties.getSpacing(); long before = twipsOf(spacing.getBefore()); @@ -5244,6 +5348,7 @@ private static void takeTheTopBorderInside(XWPFTableCell cell, double low) { if (taken > 0) { spacing.setBefore(BigInteger.valueOf(before - taken)); } + return Math.max(0, taken) / POINT_TO_TWIP; } /** @@ -5311,6 +5416,19 @@ private static double strokeWidth(DocumentStroke stroke) { return stroke == null ? 0 : Math.max(0, stroke.width()); } + /** + * How far past the page's box Word draws a panel's border above or below, in points: half its + * width outside the cell, and as much of its inner half as the cell's padding on that side + * does not hold. The page strokes the border on the box's edge, taking no room. Measured in + * Word 16 and LibreOffice alike on a 2pt border, the block beyond it stood 2pt off with no + * padding and 1pt off with 1, 2 or 4pt of it: Word sets a cell's content the whole border + * and then its margin, which is the padding less half the border, inside the row. + */ + private static double outsideTheRow(DocumentStroke border, double padding) { + double half = strokeWidth(border) / 2; + return half + Math.max(0, half - Math.max(0, padding)); + } + /** * Names in the report a node's translucent fill or strokes, which a cell's shading and its * borders hold only opaque, so they are flattened against the colour under them. @@ -6135,6 +6253,7 @@ private void warnContainerRadiusDropped(DocumentNode node) { */ private XWPFParagraph newBodyParagraph(XWPFDocument document) { resumeHere(); + nameAHangLeftOver(); XWPFParagraph para; if (cellEndsWithItsTableCloser()) { // The paragraph closing the table above is where this one goes: a second one @@ -6152,6 +6271,8 @@ private XWPFParagraph newBodyParagraph(XWPFDocument document) { // itself, and any container edge — is written here, on one side of the gap. // A card's border standing below the card took as much of the gap (writePanelPiece). double owed = carriedSpacingBefore + pendingSpacingAfter - borderBelow; + // Only space takes it: an edge below zero pulls the paragraph up, and is no border. + double borderNotTaken = Math.max(0, borderBelow - Math.max(0, carriedSpacingBefore + pendingSpacingAfter)); double above = Math.max(0, owed - pullBelow); // What the space owed cannot give of the pull, the paragraph's own top edge gives. pullLeft = Math.max(0, pullBelow - Math.max(0, owed)); @@ -6165,8 +6286,13 @@ private XWPFParagraph newBodyParagraph(XWPFDocument document) { hangingBelow = 0; double taken = Math.min(Math.max(0, above), overhang); above -= taken; - hangingOver = overhang - taken > 0 ? para : null; + // So does what of a card's border below the owed space could not take: Word draws it past + // the card's box, where the page strokes it on the box's edge (outsideTheRow). What its + // own top edge cannot give back of either stands it lower, and is named (nameTheTailNotTaken). + hangingOver = overhang - taken > 0 || borderNotTaken > 0 ? para : null; hangingOverBy = overhang - taken; + borderNotTakenOver = borderNotTaken; + tailOverNode = writing; if (above > 0) { addSpacing(para, above, 0); } @@ -8596,10 +8722,12 @@ private void applyVerticalSpacing(XWPFParagraph target, DocumentNode source) { topEdgeLineOver = target; } if (target == hangingOver) { - before = Math.max(0, before - hangingOverBy); + before = Math.max(0, before) - takeTheTailOutOf(Math.max(0, before)); } hangingOver = null; hangingOverBy = 0; + borderNotTakenOver = 0; + tailOverNode = null; if (target == pullLeftOn) { before = Math.max(0, before - pullLeft); } @@ -11166,8 +11294,7 @@ private static void holdRowAtLeast(XWPFTableRow row, double points, long beyond) /** * What the editors add to a row's written height for one cell, in twips: its top and bottom * margins, and the width of its heavier horizontal border. A panel's cell, its borders its - * own, has the other one drawn outside the height too; writePanelPiece takes that off where - * the panel's padding does not hold its top border. + * own, has the other one drawn outside the height too ({@link #holdThePanelsHeight}). */ private static long verticalMargins(XWPFTableCell cell) { org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr properties = cell.getCTTc().getTcPr(); @@ -11950,26 +12077,10 @@ private boolean closesAMeasure(DocumentNode node) { */ private void writePaintedRow(XWPFDocument document, RowNode row) throws Exception { ContainerPaint paint = paintOf(row); - // Word draws a cell's borders above and below outside its row, where the page strokes - // them on the box's edge, taking no room: a panel's row stands that much taller, and what - // follows that much lower, where no space round it takes them. - DocumentBorders borders = paint.borders() == null ? DocumentBorders.NONE : paint.borders(); - double outside = strokeWidth(borders.top()) + strokeWidth(borders.bottom()); - List lost = new ArrayList<>(2); - if (outside > 0) { - lost.add("its borders above and below are drawn outside the panel's row in Word: where no space " - + "round the row takes them, what follows stands up to " + pointsOf(outside) - + "pt lower than the page sets it"); - } - // Word starts the cell's content below its top border where its top margin is narrower; - // a panel's first paragraph takes that out of the space above it (takeTheTopBorderInside), - // and the columns' table a row's panel opens with has none. - double unheld = strokeWidth(borders.top()) - Math.max(0, row.padding().top()); - if (unheld > 0) { - lost.add("its columns stand up to " + pointsOf(unheld) + "pt lower than the page sets them, where " - + "neither its padding nor the space above it takes its top border"); - } - reportWrittenWithout(row, "written as a panel", lost); + // What of its borders above and below Word draws past its box, the space round it and its + // padding take, and what neither takes is named, as any panel's is: above by its panel + // (writePanelPiece), below by the block below (nameTheTailNotTaken). + reportWrittenWithout(row, "written as a panel"); warnContainerRadiusDropped(row); boolean onANewPage = currentCell == null && startsAPageOfItsOwn(row); if (onANewPage) { @@ -12063,6 +12174,10 @@ private void writeRow(XWPFDocument document, RowNode node, boolean inItsPanel) t boolean inAPanel = surfaceBehind != null && panelCell != null; com.demcha.compose.document.layout.PlacedNode placedRow = layout.placement(node); double rowOverhang = 0; + // A card's border below the last thing in a cell reaches past the row only by what the + // row's room under that cell does not hold, as a hanging line does. + double rowBorder = 0; + double borderAbove = borderBelow; // A row's cells are unshaded: inside a panel — its own, where it paints (writePaintedRow), or // a container's — it is a table nested in the panel's cell, and shows the panel's through them. for (int i = 0; i < node.children().size(); i++) { @@ -12076,6 +12191,7 @@ private void writeRow(XWPFDocument document, RowNode node, boolean inItsPanel) t leftMarginInCell = placedColumns ? child : null; cellHang = -hang; cellOverhang = 0; + borderBelow = 0; try { writeRowCellChild(cell, child); } finally { @@ -12083,10 +12199,16 @@ private void writeRow(XWPFDocument document, RowNode node, boolean inItsPanel) t leftMarginInCell = previousHeld; cellHang = 0; } - rowOverhang = Math.max(rowOverhang, cellOverhang - roomBelowInItsRow(child, placedRow, node)); + double roomBelow = roomBelowInItsRow(child, placedRow, node); + rowOverhang = Math.max(rowOverhang, cellOverhang - roomBelow); + // Where the layout does not say, the border is the row's whole, and named if nothing takes it. + rowBorder = Math.max(rowBorder, borderBelow - (Double.isInfinite(roomBelow) ? 0 : roomBelow)); + borderBelow = 0; cellOverhang = 0; applyRowVerticalAlign(cell, node.verticalAlign()); } + borderBelow = Math.max(borderAbove, rowBorder); + borderBelowCell = null; giveTheLastCellItsInk(table, node, placedColumns); // Anywhere, a row whose tallest child is one Word holds nothing of in its cell — a // picture drawn where the page puts it, a badge beside a heading — is only as tall there @@ -13720,14 +13842,7 @@ private double nestedTableWidth() { private XWPFTable newTable(XWPFDocument document, int rows, int columns) { resumeHere(); - // Text hanging below the band above took that much of the gap above this table, and - // so did a card's border standing below the card (writePanelPiece). - pendingSpacingAfter = Math.max(0, pendingSpacingAfter - hangingBelow - borderBelow); - hangingBelow = 0; - borderBelow = 0; - if (currentCell == null ? endsWithATable(document.getBodyElements()) : cellEndsWithItsTableCloser()) { - separateFromTheTableAbove(document); - } + nameAHangLeftOver(); // A container edge still waiting for a paragraph stood above this table, and a table // carries no space above itself: it is owed with the rest of the space above, which // the paragraph before the table holds below itself. Left waiting, it landed on the @@ -13735,6 +13850,20 @@ private XWPFTable newTable(XWPFDocument document, int rows, int columns) { // the space out of the page and everything below the table moved up. owePendingSpacingAfter(carriedSpacingBefore); carriedSpacingBefore = 0; + // Text hanging below the band above took that much of the gap above this table, and + // so did a card's border standing below the card (writePanelPiece): what the gap could + // not give of either, and of the paragraph between two tables, stands the table lower. + double hangNotTaken = Math.max(0, hangingBelow - Math.max(0, pendingSpacingAfter)); + double borderNotTaken = Math.max(0, borderBelow - Math.max(0, pendingSpacingAfter - hangingBelow)); + pendingSpacingAfter = Math.max(0, pendingSpacingAfter - hangingBelow - borderBelow); + hangingBelow = 0; + borderBelow = 0; + double separatorNotTaken = 0; + if (currentCell == null ? endsWithATable(document.getBodyElements()) : cellEndsWithItsTableCloser()) { + separatorNotTaken = Math.max(0, SEPARATOR_POINTS - pendingSpacingAfter); + separateFromTheTableAbove(document); + } + nameTheTailNotTaken(writing, borderNotTaken, hangNotTaken, separatorNotTaken); // With no paragraph before it in the body — the table opens the document or a section, // or follows a page break — a hairline one carries it: ClassicInvoice opens with a row // under its page padding, and without it stood against the paper's top edge in Word. @@ -14100,9 +14229,12 @@ private void writeInCell(XWPFTableCell cell, CellContent content) throws Excepti double previousOwed = pendingSpacingAfter; double previousPull = pullBelow; double previousBorderBelow = borderBelow; + XWPFTableCell previousBorderBelowCell = borderBelowCell; double previousHangingBelow = hangingBelow; XWPFParagraph previousHangingOver = hangingOver; double previousHangingOverBy = hangingOverBy; + double previousBorderNotTakenOver = borderNotTakenOver; + DocumentNode previousTailOverNode = tailOverNode; double previousInsetLeft = insetLeft; double previousInsetRight = insetRight; double previousTextShift = cellTextShift; @@ -14114,6 +14246,7 @@ private void writeInCell(XWPFTableCell cell, CellContent content) throws Excepti pendingSpacingAfter = 0; pullBelow = 0; borderBelow = 0; + borderBelowCell = null; forgetTheHang(); // A cell's content is measured from the cell's own edge, which its margins already // keep clear of the border; the containers around the table have nothing to add. A row @@ -14132,6 +14265,8 @@ private void writeInCell(XWPFTableCell cell, CellContent content) throws Excepti && carriedSpacingBefore + pendingSpacingAfter > 0 && cell.getBodyElements().isEmpty()) { holdToHairline(newBodyParagraph(cell.getXWPFDocument())); } + // A hang its last paragraph was to take out of its own top edge and never did. + nameAHangLeftOver(); // A line hanging below the cell's last block takes the space the cell owes under it // first, as it takes the gap above the next block in the flow; what it reaches past // that makes Word's cell taller than its content on the page. @@ -14151,10 +14286,14 @@ private void writeInCell(XWPFTableCell cell, CellContent content) throws Excepti pullBelow = previousPull; // A card's border below the last thing in a cell stands below the row too, where // Word makes the row as tall as its tallest cell; the cell beside it starts clear. + // The row's, it is no longer one card's padding to take. + borderBelowCell = previousBorderBelow >= borderBelow ? previousBorderBelowCell : null; borderBelow = Math.max(previousBorderBelow, borderBelow); hangingBelow = previousHangingBelow; hangingOver = previousHangingOver; hangingOverBy = previousHangingOverBy; + borderNotTakenOver = previousBorderNotTakenOver; + tailOverNode = previousTailOverNode; insetLeft = previousInsetLeft; insetRight = previousInsetRight; cellTextShift = previousTextShift; @@ -14269,7 +14408,7 @@ private void writeSpacer(XWPFDocument document, SpacerNode node) throws Exceptio double height = Math.max(0, node.height() - SEPARATOR_POINTS); // Text that hung below the band above takes its place out of this height first. if (hangingOver == para) { - height = Math.max(0, height - hangingOverBy); + height -= takeTheTailOutOf(height); forgetTheHang(); } // So does a pull out of the paragraph above that the space above it did not give. @@ -14294,6 +14433,84 @@ private void forgetTheHang() { hangingBelow = 0; hangingOver = null; hangingOverBy = 0; + borderNotTakenOver = 0; + tailOverNode = null; + } + + /** + * Names a hang a paragraph was to take out of its own top edge and never did — nothing of + * its own was written above it (applyVerticalSpacing, writeSpacer) — before the next block + * takes the hang's place: all of it stands that paragraph lower. + */ + private void nameAHangLeftOver() { + if (hangingOver != null) { + nameTheTailNotTaken(tailOverNode, borderNotTakenOver, hangingOverBy, 0); + hangingOver = null; + hangingOverBy = 0; + borderNotTakenOver = 0; + tailOverNode = null; + } + } + + /** + * Takes what the block above left hanging over a paragraph — the line hanging below that block + * and what of a panel's border below the space between them did not take — out of + * {@code room}, space of the paragraph's own, and names what that does not hold. + * + * @return the points of {@code room} it takes + */ + private double takeTheTailOutOf(double room) { + double hangTaken = Math.min(room, hangingOverBy); + double borderTaken = Math.min(room - hangTaken, borderNotTakenOver); + nameTheTailNotTaken(tailOverNode, borderNotTakenOver - borderTaken, hangingOverBy - hangTaken, 0); + return hangTaken + borderTaken; + } + + /** + * How far past the space it is taken out of a reach may go unnamed, in points: what a block + * leaves below itself past the space below it, or a panel's top border past the space above it. + */ + private static final double TAIL_CLEARANCE = 0.05; + + /** + * Names how much lower than the page sets it a block stands in Word, and what follows with + * it, where what the block above leaves below itself reaches past the space the page keeps + * between them. Each of these is taken out of that space first, and only what it could not + * take is named: + *
    + *
  • a panel's border below, which Word draws past the panel's box ({@link #outsideTheRow}); + * what of it the space does not take, the panel's padding below takes, the border then + * drawn that much inside the panel's edge;
  • + *
  • a line hanging below the box of the block above — a band's text held to its marker, a + * cell's last line held to its icon (hangingBelow);
  • + *
  • the paragraph Word needs between two tables, which the page does not have + * ({@link #separateFromTheTableAbove}).
  • + *
+ * + * @param node the block that stands lower, or {@code null} where no block of the writer's is + */ + private void nameTheTailNotTaken(DocumentNode node, double border, double hang, double separator) { + if (border > 0 && borderBelowCell != null) { + border = Math.max(0, border - takeOffTheCellMargin(borderBelowCell, false, border)); + borderBelowCell = null; + } + double all = Math.max(0, border) + Math.max(0, hang) + Math.max(0, separator); + if (!(all > TAIL_CLEARANCE)) { + return; + } + List held = new ArrayList<>(3); + if (border > 0) { + held.add("the border Word draws past the box of the panel above it (" + pointsOf(border) + "pt)"); + } + if (hang > 0) { + held.add("the line hanging below the block above it (" + pointsOf(hang) + "pt)"); + } + if (separator > 0) { + held.add("the paragraph Word keeps between two tables (" + pointsOf(separator) + "pt)"); + } + report.add(DocxExportReport.Severity.APPROXIMATED, "space above", node == null ? null : layout.pathOf(node), + "it stands " + pointsOf(all) + "pt lower than the page sets it, and what follows with it: the space the " + + "page leaves above it does not hold " + listed(held)); } private void writePageBreak(XWPFDocument document) { diff --git a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxContainerSpacingTest.java b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxContainerSpacingTest.java index 6b7a9b4f4..ef72a603f 100644 --- a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxContainerSpacingTest.java +++ b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxContainerSpacingTest.java @@ -163,17 +163,19 @@ void aSpacerUnderATableInACellIsTheTablesCloserAndItsHeightOnce() throws Excepti @Test void theBordersOfTwoCardsComeOutOfTheSpaceBetweenThem() throws Exception { - // Word draws a row's top and bottom borders outside its shading, where the page strokes - // them on the card's edge: written whole, the space between two outlined cards came out - // their borders wider, and an invoice of three such cards ran onto a second page. + // Word draws a card's top and bottom borders past its shading, where the page strokes them + // on the card's edge: written whole, the space between two outlined cards came out wider, + // and an invoice of three such cards ran onto a second page. Half a border reaches past + // the card whatever its padding, the inner half only where the padding does not hold it + // (outsideTheRow): with 6pt of padding, half of each 2pt border. long filled = spaceBetweenTwoCards(null); long outlined = spaceBetweenTwoCards(DocumentStroke.of(DocumentColor.rgb(90, 90, 90), 2)); assertThat(filled).as("filled cards: the section's spacing, less the separator's hairline") .isBetween(12 * 20L - 2, 12 * 20L); assertThat(filled - outlined) - .as("the second card's top border and the first one's bottom border come out of it") - .isEqualTo(4 * 20L); + .as("half of the second card's top border and of the first one's bottom border come out of it") + .isEqualTo(2 * 20L); } @Test @@ -290,11 +292,12 @@ void aRowOpeningATablesCellIsWrittenAsBefore() throws Exception { @Test void aCardsBottomBorderComesOutOfTheSpaceAboveTheParagraphAfterIt() throws Exception { // With no margin to take it from, the border stood below the card and the paragraph - // after it landed a border lower than on the page. + // after it landed lower than on the page: by half the 2pt border, the 6pt padding holding + // its inner half (outsideTheRow). Taking the whole border stood the paragraph a point high. long filled = spaceAboveTheParagraphAfterACard(null, 0); long outlined = spaceAboveTheParagraphAfterACard(DocumentStroke.of(DocumentColor.rgb(90, 90, 90), 2), 0); - assertThat(filled - outlined).isEqualTo(2 * 20L); + assertThat(filled - outlined).isEqualTo(20L); } @Test @@ -302,7 +305,7 @@ void aCardsBottomMarginTakesItsBorderFirst() throws Exception { long filled = spaceAboveTheParagraphAfterACard(null, 5); long outlined = spaceAboveTheParagraphAfterACard(DocumentStroke.of(DocumentColor.rgb(90, 90, 90), 2), 5); - assertThat(filled - outlined).as("the border, out of the margin; nothing more").isEqualTo(2 * 20L); + assertThat(filled - outlined).as("what reaches past the card, out of the margin; nothing more").isEqualTo(20L); } private static long spaceAboveTheParagraphAfterACard(DocumentStroke stroke, double marginBelow) throws Exception { diff --git a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxNodeFieldLedgerTest.java b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxNodeFieldLedgerTest.java index dc88cae7b..96a7a463a 100644 --- a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxNodeFieldLedgerTest.java +++ b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxNodeFieldLedgerTest.java @@ -93,6 +93,13 @@ private record Entry(Fate fate, String note) { private static final String PANEL_TRANSLUCENCY = "its translucency, as a panel's, flattened against the colour " + "under it, a border's against the panel's fill where it has " + "one; any other is written"; + // Word draws a panel's borders above and below past its box; what the space round it and its + // padding do not take stands the content, or the block below, lower, and is reported. + private static final String PANEL_BORDERS = "its translucency, as a panel's, flattened against the colour " + + "under it, a border's against the panel's fill where it has one; " + + "what of a border above or below Word draws past the panel's box " + + "that neither the space round it nor its padding takes; any other " + + "is written"; private static final String RULE_TRANSLUCENCY = "its translucency, as a rule's, flattened against the colour " + "under it; drawn, its alpha is written; any other is written"; private static final String CELL_TRANSLUCENCY = "the translucency of a cell's fill, flattened against the colour " @@ -105,9 +112,9 @@ private record Entry(Fate fate, String note) { + "layers or where a stack's column measures the space round it to its " + "text, with a padding below zero or a column hanging into it, and " + "with a margin below zero above or below it or at a side in a cell; " - + "its translucency, as a panel's, borders above and below, which Word " - + "draws outside the panel's row, and a top border its padding does not " - + "take; any other is written, as a panel"; + + "its translucency, as a panel's, and what of a border above or below " + + "Word draws past the panel's box that neither the space round it nor " + + "its padding takes; any other is written, as a panel"; private static final Map, Map> NODES = new LinkedHashMap<>(); private static final Map OUTPUT_OPTIONS = fields( @@ -148,8 +155,8 @@ private record Entry(Fate fate, String note) { "margin:REPORTED:in the chart's note; above and below; below a block a band or a column measures from, written", "padding:REPORTED:in the chart's note; above and below; below a block a band or a column measures from, written"); node(ContainerNode.class, "name:INERT", "children:WRITTEN", "spacing:WRITTEN", "padding:WRITTEN", - "margin:WRITTEN", "fillColor:REPORTED:" + PANEL_TRANSLUCENCY, "stroke:REPORTED:" + PANEL_TRANSLUCENCY, - "cornerRadius:REPORTED", "borders:REPORTED:" + PANEL_TRANSLUCENCY, + "margin:WRITTEN", "fillColor:REPORTED:" + PANEL_TRANSLUCENCY, "stroke:REPORTED:" + PANEL_BORDERS, + "cornerRadius:REPORTED", "borders:REPORTED:" + PANEL_BORDERS, "anchor:REPORTED:as a layer stack's column, which has no bookmark; in the flow it is bookmarked", "bookmarkOptions:REPORTED", "flowWidth:REPORTED:of an unpainted one, a panel in a table cell and a layer stack's column"); node(EllipseNode.class, "name:INERT", "width:WRITTEN", "height:WRITTEN", "fillColor:WRITTEN", @@ -243,8 +250,8 @@ private record Entry(Fate fate, String note) { node(com.demcha.compose.document.layout.HorizontalBandContentNode.class, "name:INERT", "key:INERT", "slot:WRITTEN", "child:WRITTEN"); node(SectionNode.class, "name:INERT", "children:WRITTEN", "spacing:WRITTEN", "padding:WRITTEN", - "margin:WRITTEN", "fillColor:REPORTED:" + PANEL_TRANSLUCENCY, "stroke:REPORTED:" + PANEL_TRANSLUCENCY, - "cornerRadius:REPORTED", "borders:REPORTED:" + PANEL_TRANSLUCENCY, + "margin:WRITTEN", "fillColor:REPORTED:" + PANEL_TRANSLUCENCY, "stroke:REPORTED:" + PANEL_BORDERS, + "cornerRadius:REPORTED", "borders:REPORTED:" + PANEL_BORDERS, "keepTogether:WRITTEN", "anchor:REPORTED:as a layer stack's column, which has no bookmark; in the flow it is bookmarked", "bleed:REPORTED:of a panel the page bleeds, in the flow it pages", diff --git a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelHeightTest.java b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelHeightTest.java index 18876b9a5..8faf56c67 100644 --- a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelHeightTest.java +++ b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelHeightTest.java @@ -190,28 +190,31 @@ void aPanelOpeningACellTakesItsTopBorderFromTheSpaceOverItsFirstLine() throws Ex assertThat(beforeOf(bordered)).as("the room over the heading, less the 1pt border") .isEqualTo(beforeOf(plain) - 20); - // The height written is already less the border LibreOffice adds to it; it is also less - // the border taken over the heading, which Word draws above the row's height. - assertThat(heightOf(outerTableOf(bordered))).as("the row's height, less the border twice") - .isEqualTo(heightOf(outerTableOf(plain)) - 20 - 20); + // The editors read the height written as the content's, its borders round it: it is less + // the border taken over the heading, which the content then holds no more. + assertThat(heightOf(outerTableOf(bordered))).as("the content's height, less the border taken over the heading") + .isEqualTo(heightOf(outerTableOf(plain)) - 20); } @Test void aPaddedPanelOpeningACellKeepsTheSpaceOverItsFirstLine() throws Exception { - // Its top margin is wider than its border, which Word then draws inside the margin. + // Word sets a cell's content its whole border and then its margin inside the row, the page + // its padding inside the panel's edge; with no space above to take the outer half of the + // border (outsideTheRow), the padding takes it, and the room over the heading is kept. XWPFTableCell bordered = panelInARow(1, 10); XWPFTableCell plain = panelInARow(0, 10); assertThat(beforeOf(bordered)).isEqualTo(beforeOf(plain)); - // Its margins are half a border narrower top and bottom, its border LibreOffice's - // allowance: the height held is the same, nothing more taken off for Word. + assertThat(topMarginOf(bordered)).as("the padding, less the whole border").isEqualTo(topMarginOf(plain) - 20); + // The editors read a panel's written height as its content's, its margins and borders + // round it: the same padding holds the same content, bordered or not. assertThat(heightOf(outerTableOf(bordered))).isEqualTo(heightOf(outerTableOf(plain))); } @Test void aPanelRuledAboveOnlyOpeningACellKeepsTheHeightItHeld() throws Exception { - // Word draws the one border outside the row's height, where LibreOffice's allowance for it - // already took it off; nothing more comes off for it. + // Its one border is taken over its heading, as an outlined panel's top border is: the + // content's height held is that much less, and nothing more comes off for it. XWPFTableCell ruled = panelInARow(1, 0, true); XWPFTableCell plain = panelInARow(0, 0, false); @@ -266,6 +269,11 @@ private static long beforeOf(XWPFTableCell cell) { return spacing.isSetBefore() ? ((Number) spacing.getBefore()).longValue() : 0; } + /** A cell's top margin as written, in twips. */ + private static long topMarginOf(XWPFTableCell cell) { + return ((Number) cell.getCTTc().getTcPr().getTcMar().getTop().getW()).longValue(); + } + /** A table's first row's written height, which the export writes "at least". */ private static int heightOf(XWPFTable table) { org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr properties = table.getRow(0).getCtRow().getTrPr(); diff --git a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelTailTest.java b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelTailTest.java new file mode 100644 index 000000000..ab611af9a --- /dev/null +++ b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelTailTest.java @@ -0,0 +1,540 @@ +package com.demcha.compose.document.backend.semantic.docx; + +import com.demcha.compose.GraphCompose; +import com.demcha.compose.document.api.DocumentSession; +import com.demcha.compose.document.dsl.PageFlowBuilder; +import com.demcha.compose.document.dsl.SectionBuilder; +import com.demcha.compose.document.node.InlineImageAlignment; +import com.demcha.compose.document.style.DocumentBorders; +import com.demcha.compose.document.style.DocumentColor; +import com.demcha.compose.document.style.DocumentInsets; +import com.demcha.compose.document.style.DocumentStroke; +import com.demcha.compose.document.style.DocumentTextStyle; +import com.demcha.compose.document.svg.SvgIcon; +import com.demcha.compose.document.table.DocumentTableCell; +import com.demcha.compose.document.table.DocumentTableColumn; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.apache.poi.xwpf.usermodel.XWPFTableCell; +import org.junit.jupiter.api.Test; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing; + +import java.io.ByteArrayInputStream; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * What a panel leaves below and above itself in Word, and what takes it. + * + *

Word sets a panel's content its whole border and then its margin inside the row, where the + * page strokes the border on the panel's edge and sets the content its padding inside it: half a + * border reaches past the panel, and its inner half too where the padding is thinner than that. + * The space round the panel takes it first, then the panel's padding, the border then drawn that + * much inside the panel's edge; what neither takes stands the block beyond it lower, and is named. + * So is a panel's last line hanging past its content, which its padding takes first, and the + * paragraph Word keeps between two tables. Measured in Word 16 and LibreOffice alike.

+ * + * @author Artem Demchyshyn + */ +class DocxPanelTailTest { + + private static final DocumentColor SURFACE = DocumentColor.rgb(238, 243, 249); + private static final DocumentStroke RULE = DocumentStroke.of(DocumentColor.rgb(26, 86, 148), 2); + private static final SvgIcon ICON = SvgIcon.parse("" + + ""); + private static final DocumentTextStyle SMALL = DocumentTextStyle.DEFAULT.withSize(7); + + @Test + void aPaddedCardsBorderBelowComesOutOfItsPaddingWhereNoSpaceTakesIt() throws Exception { + Exported exported = export(page -> page.addSection("Card", card -> card.fillColor(SURFACE) + .borders(DocumentBorders.bottom(RULE)).padding(DocumentInsets.of(4)).addParagraph("Inside")) + .addParagraph("After")); + + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + assertThat(bottomMargin(panel(exported))).as("its padding, less the whole border").isEqualTo(2 * 20); + assertThat(before(paragraph(exported, "After"))).isZero(); + } + + @Test + void theSpaceBelowACardTakesItsBorderBeforeItsPaddingDoes() throws Exception { + // There the border stands where the page strokes it, half outside the card. + Exported exported = export(page -> page.addSection("Card", card -> card.fillColor(SURFACE) + .borders(DocumentBorders.bottom(RULE)).padding(DocumentInsets.of(4)).addParagraph("Inside")) + .addParagraph(p -> p.text("After").margin(new DocumentInsets(10, 0, 0, 0)))); + + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + assertThat(bottomMargin(panel(exported))).as("its padding, less half the border").isEqualTo(3 * 20); + assertThat(before(paragraph(exported, "After"))).as("the gap, less half the border").isEqualTo(9 * 20); + } + + @Test + void aCardWithNoPaddingNamesTheBorderNothingTakes() throws Exception { + Exported exported = export(page -> page.addSection("Card", card -> card.fillColor(SURFACE) + .borders(DocumentBorders.bottom(RULE)).addParagraph("Inside")) + .addParagraph(p -> p.name("After").text("After"))); + + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.severity()).isEqualTo(DocxExportReport.Severity.APPROXIMATED); + assertThat(note.path()).contains("After"); + assertThat(note.detail()).isEqualTo("it stands 2pt lower than the page sets it, and what follows with it: the " + + "space the page leaves above it does not hold the border Word draws past " + + "the box of the panel above it (2pt)"); + }); + } + + @Test + void aCardWithNoPaddingNamesItsTopBorderNothingTakes() throws Exception { + Exported exported = export(page -> page.addParagraph("Before").addSection("Card", card -> card + .fillColor(SURFACE).borders(DocumentBorders.top(RULE)).addParagraph("Inside"))); + + assertThat(exported.report().bySubject().get("SectionNode")).singleElement().satisfies(note -> { + assertThat(note.severity()).isEqualTo(DocxExportReport.Severity.APPROXIMATED); + assertThat(note.path()).contains("Card"); + assertThat(note.detail()).isEqualTo("its content stands 2pt lower than the page sets it, and what follows " + + "up to as much: Word sets it below the whole of its top border, and " + + "neither the space above it nor its padding takes what of the border " + + "reaches past the panel's box"); + }); + } + + @Test + void twoTouchingCardsNameAllThatStandsTheSecondLowerAtOnce() throws Exception { + // The first one's border below, the second one's above, and the paragraph Word keeps + // between two tables: one note, the whole of it. + Exported exported = export(page -> page + .addSection("First", card -> card.fillColor(SURFACE).borders(DocumentBorders.bottom(RULE)) + .addParagraph("One")) + .addSection("Second", card -> card.fillColor(SURFACE).borders(DocumentBorders.top(RULE)) + .addParagraph("Two"))); + + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("Second"); + assertThat(note.detail()).isEqualTo("it stands 2.1pt lower than the page sets it, and what follows with it: " + + "the space the page leaves above it does not hold the border Word draws " + + "past the box of the panel above it (2pt) and the paragraph Word keeps " + + "between two tables (0.1pt)"); + }); + assertThat(exported.report().bySubject().get("SectionNode")).singleElement() + .satisfies(note -> assertThat(note.detail()).startsWith("its content stands 2pt lower")); + } + + @Test + void aCardsBorderCarriedOutOfARowsCellIsNoLongerItsPaddingsToTake() throws Exception { + // Below the row, the border is the row's: Word makes the row as tall as its tallest cell, + // which the card's padding does not decide. + Exported exported = export(page -> page.addRow(row -> row + .addSection("Card", card -> card.fillColor(SURFACE).borders(DocumentBorders.bottom(RULE)) + .padding(DocumentInsets.of(4)).addParagraph("Inside")) + .addParagraph("Beside")) + .addParagraph(p -> p.name("After").text("After"))); + XWPFTableCell card = exported.document().getTables().get(0).getRow(0).getCell(0).getTables().get(0) + .getRow(0).getCell(0); + + assertThat(bottomMargin(card)).as("its padding, less half the border").isEqualTo(3 * 20); + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("After"); + assertThat(note.detail()).isEqualTo("it stands 1pt lower than the page sets it, and what follows with it: the " + + "space the page leaves above it does not hold the border Word draws past " + + "the box of the panel above it (1pt)"); + }); + } + + @Test + void aCardsBorderCarriedOutOfATablesCellIsNoLongerItsPaddingsToTake() throws Exception { + var card = new com.demcha.compose.document.dsl.SectionBuilder().name("Card").fillColor(SURFACE) + .borders(DocumentBorders.bottom(RULE)).padding(DocumentInsets.of(4)) + .addParagraph("Inside").build(); + Exported exported = export(page -> page.addTable(table -> table.columns(DocumentTableColumn.fixed(120)) + .rowCells(DocumentTableCell.node(card))) + .addParagraph(p -> p.name("After").text("After"))); + XWPFTableCell inner = exported.document().getTables().get(0).getRow(0).getCell(0).getTables().get(0) + .getRow(0).getCell(0); + + assertThat(bottomMargin(inner)).as("its padding, less half the border").isEqualTo(3 * 20); + } + + @Test + void aPaddedCardsTopBorderComesOutOfItsPaddingWhereNoSpaceAboveTakesIt() throws Exception { + Exported exported = export(page -> page.addParagraph("Before").addSection("Card", card -> card + .fillColor(SURFACE).borders(DocumentBorders.top(RULE)).padding(DocumentInsets.of(4)).addParagraph("Inside"))); + + assertThat(exported.report().bySubject()).doesNotContainKey("SectionNode"); + assertThat(topMargin(panel(exported))).as("its padding, less the whole border").isEqualTo(2 * 20); + } + + @Test + void anOutlinedCardHoldsTheHeightOfItsContent() throws Exception { + // The editors read a panel's written height as its content's, its margins and both its + // borders round it: held less its margins and one border, an outlined card padded 4pt + // stood a point taller than the page's. + double height; + byte[] docx; + AtomicReference report = new AtomicReference<>(); + try (DocumentSession session = GraphCompose.document().pageSize(400, 400).margin(DocumentInsets.of(20)).create()) { + session.pageFlow(page -> page.addSection("Card", card -> card.fillColor(SURFACE).stroke(RULE) + .padding(DocumentInsets.of(4)).addParagraph("Inside")).addParagraph("After")); + height = session.layoutGraph().nodes().stream().filter(node -> "Card".equals(node.semanticName())) + .findFirst().orElseThrow().placementHeight(); + docx = session.export(new DocxSemanticBackend(report::set)); + } + try (XWPFDocument document = new XWPFDocument(new ByteArrayInputStream(docx))) { + var row = document.getTables().get(0).getRow(0); + assertThat(row.getHeight()).as("the page's height, less its padding").isEqualTo(Math.round((height - 8) * 20)); + assertThat(report.get().bySubject()).doesNotContainKey("space above").doesNotContainKey("SectionNode"); + } + } + + @Test + void aShapesBordersStayInsideItsOutline() throws Exception { + // Its layers are centred in it, and its outline holds its height whole: nothing of its + // borders reaches past it, and nothing is named for them. + var chip = new com.demcha.compose.document.dsl.ShapeContainerBuilder().name("Chip").roundedRect(90, 17.5, 4) + .stroke(DocumentStroke.of(DocumentColor.rgb(26, 86, 148), 1.1)) + .center(new com.demcha.compose.document.dsl.ParagraphBuilder().text("09:00").build()).build(); + Exported exported = export(page -> page.addTable(table -> table + .columns(DocumentTableColumn.auto(), DocumentTableColumn.fixed(100)) + .rowCells(DocumentTableCell.text("Mon"), DocumentTableCell.node(chip))) + .addParagraph("After")); + + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + assertThat(exported.report().notes()).noneSatisfy(note -> assertThat(note.detail()).contains("stands")); + } + + @Test + void aPaddedShapeHoldsItsOutlineLessBothBordersAndItsMargins() throws Exception { + // The page draws the borders and the padding inside the outline: the content held is + // what is left of it, both borders off, as the editors add both round the row's height. + var chip = new com.demcha.compose.document.dsl.ShapeContainerBuilder().name("Chip").roundedRect(90, 17.5, 4) + .padding(DocumentInsets.of(2)).stroke(DocumentStroke.of(DocumentColor.rgb(26, 86, 148), 1.1)) + .center(new com.demcha.compose.document.dsl.ParagraphBuilder().text("09:00").build()).build(); + Exported exported = export(page -> page.addTable(table -> table + .columns(DocumentTableColumn.auto(), DocumentTableColumn.fixed(100)) + .rowCells(DocumentTableCell.text("Mon"), DocumentTableCell.node(chip)))); + XWPFTableCell cell = exported.document().getTables().get(0).getRow(0).getCell(1).getTables().get(0) + .getRow(0).getCell(0); + + assertThat(topMargin(cell)).as("its padding, less half its border").isEqualTo(29); + assertThat(bottomMargin(cell)).isEqualTo(29); + // The heavier border at the width Word is given, nine eighths of a point; the lighter one + // at its own. + assertThat(cell.getTableRow().getHeight()).as("17.5pt, less both margins and both borders") + .isEqualTo(Math.round((17.5 - 1.1) * 20) - 2 * 29 - Math.round(9 / 8.0 * 20)); + } + + @Test + void aPanelsHangingLastLineComesOutOfItsPaddingBelow() throws Exception { + Exported exported = export(page -> page.spacing(10).addSection("Card", card -> { + card.fillColor(SURFACE).padding(DocumentInsets.bottom(5)); + contact(card); + }).addParagraph("After")); + long down = reachBelow(exported, "Iconed"); + + assertThat(down).as("the line reaches below the page's").isPositive(); + assertThat(bottomMargin(panel(exported))).as("the padding less the reach").isEqualTo(5 * 20 - down); + assertThat(before(paragraph(exported, "After"))).as("the whole gap").isEqualTo(10 * 20); + } + + @Test + void aPanelsHangingLastLineWithNoPaddingTakesTheGapUnderIt() throws Exception { + Exported exported = export(page -> page.spacing(10).addSection("Card", card -> { + card.fillColor(SURFACE); + contact(card); + }).addParagraph("After")); + long down = reachBelow(exported, "Iconed"); + + assertThat(down).as("the line reaches below the page's").isPositive(); + assertThat(before(paragraph(exported, "After"))).as("the gap, less the reach").isEqualTo(10 * 20 - down); + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + } + + @Test + void aPanelsHangNothingTakesIsNamed() throws Exception { + Exported exported = export(page -> page.addSection("Card", card -> { + card.fillColor(SURFACE); + contact(card); + }).addParagraph(p -> p.name("After").text("After"))); + String reach = points(reachBelow(exported, "Iconed")); + + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("After"); + assertThat(note.detail()).isEqualTo("it stands " + reach + "pt lower than the page sets it, and what follows " + + "with it: the space the page leaves above it does not hold the line " + + "hanging below the block above it (" + reach + "pt)"); + }); + } + + @Test + void aShapesHangingLineIsHeldInItsOutline() throws Exception { + // Its layers are centred in the outline's height, which holds the line: its padding is + // left as it is, and nothing is named. + var chip = new com.demcha.compose.document.dsl.ShapeContainerBuilder().name("Chip").roundedRect(90, 30, 4) + .padding(new DocumentInsets(0, 0, 6, 0)).fillColor(SURFACE) + .center(new com.demcha.compose.document.dsl.ParagraphBuilder().textStyle(SMALL).inlineText("GitHub ", SMALL) + .inlineSvgIcon(ICON, 10.5, InlineImageAlignment.CENTER, -1.35, null).build()).build(); + Exported exported = export(page -> page.addTable(table -> table + .columns(DocumentTableColumn.auto(), DocumentTableColumn.fixed(100)) + .rowCells(DocumentTableCell.text("Mon"), DocumentTableCell.node(chip))) + .addParagraph("After")); + XWPFTableCell cell = exported.document().getTables().get(0).getRow(0).getCell(1).getTables().get(0) + .getRow(0).getCell(0); + + assertThat(bottomMargin(cell)).isEqualTo(6 * 20); + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + } + + @Test + void aCardsBorderEndingAPanelComesOutOfThePanelsPadding() throws Exception { + // The inner card's border reaches past its box into the outer panel's padding, which + // takes it: the outer panel stays the page's height. + Exported exported = export(page -> page.addSection("Outer", outer -> outer.fillColor(SURFACE) + .padding(DocumentInsets.of(6)).addParagraph("Lead") + .addSection("Inner", inner -> inner.fillColor(DocumentColor.WHITE) + .borders(DocumentBorders.bottom(RULE)).addParagraph("Inside"))) + .addParagraph(p -> p.name("After").text("After"))); + + assertThat(bottomMargin(panel(exported))).as("its padding, less the inner border").isEqualTo(4 * 20); + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + } + + @Test + void aCardsBorderEndingAPanelItsPaddingCannotHoldIsNamed() throws Exception { + Exported exported = export(page -> page.addSection("Outer", outer -> outer.fillColor(SURFACE) + .padding(DocumentInsets.of(1)).addParagraph("Lead") + .addSection("Inner", inner -> inner.fillColor(DocumentColor.WHITE) + .borders(DocumentBorders.bottom(RULE)).addParagraph("Inside"))) + .addParagraph(p -> p.name("After").text("After"))); + + assertThat(bottomMargin(panel(exported))).isZero(); + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("After"); + assertThat(note.detail()).isEqualTo("it stands 1pt lower than the page sets it, and what follows with it: the " + + "space the page leaves above it does not hold the border Word draws past " + + "the box of the panel above it (1pt)"); + }); + } + + @Test + void aCardsBorderBesideATallerCellReachesNoFurtherThanTheRow() throws Exception { + // The row is as tall as the cell beside the card, whose room under the card holds its + // border: what follows stands where the page sets it, and nothing is named. + Exported exported = export(page -> page.addRow(row -> row + .addSection("Card", card -> card.fillColor(SURFACE).borders(DocumentBorders.bottom(RULE)) + .addParagraph("Inside")) + .addSection("Tall", tall -> { + for (int line = 0; line < 4; line++) { + tall.addParagraph("Line"); + } + })) + .addParagraph(p -> p.name("After").text("After"))); + + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + } + + @Test + void aMarginBelowZeroUnderAPanelIsNoBorder() throws Exception { + // It pulls what follows up, as a paragraph's does: the panel keeps its padding, and no + // border is named. + Exported exported = export(page -> page.addSection("Card", card -> card.fillColor(SURFACE) + .padding(DocumentInsets.of(8)).margin(new DocumentInsets(0, 0, -4, 0)).addParagraph("Inside")) + .addParagraph(p -> p.name("After").text("After"))); + + assertThat(bottomMargin(panel(exported))).isEqualTo(8 * 20); + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + } + + @Test + void aContainersEdgeAboveATableTakesTheTailOfTheBlockAbove() throws Exception { + // The section's top padding is space above its table, as above a paragraph. + Exported exported = export(page -> page.addSection("Card", card -> card.fillColor(SURFACE) + .borders(DocumentBorders.bottom(RULE)).addParagraph("Inside")) + .addSection("Plain", plain -> plain.padding(new DocumentInsets(10, 0, 0, 0)).addTable(this::first))); + + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + } + + @Test + void aTailLeftOverTheLastBlockIsNamed() throws Exception { + // A list item takes no space above out of its own top edge: the border the space above + // it does not hold is named all the same, at the document's end. + Exported exported = export(page -> page.addSection("Card", card -> card.fillColor(SURFACE) + .borders(DocumentBorders.bottom(RULE)).addParagraph("Inside")) + .addList(list -> list.addItem("Only"))); + + assertThat(exported.report().bySubject().get("space above")).singleElement() + .satisfies(note -> assertThat(note.detail()).startsWith("it stands 2pt lower")); + } + + @Test + void aPanelTheLayoutMovesToANewPageLeavesTheTailAbove() throws Exception { + // What the card above leaves below itself stays on its page, and the padded card on the + // next one names nothing for it. + Exported exported = export(page -> page.addSpacer(spacer -> spacer.size(0, 480)) + .addSection("First", card -> card.fillColor(SURFACE).borders(DocumentBorders.bottom(RULE)) + .addParagraph("One")) + .addSection("Second", card -> card.keepTogether().fillColor(SURFACE).borders(DocumentBorders.top(RULE)) + .padding(DocumentInsets.of(4)).addParagraph("Two").addParagraph("Two").addParagraph("Two") + .addParagraph("Two").addParagraph("Two").addParagraph("Two"))); + + assertThat(exported.pages().get("Second")).as("the layout moves it to the next page").isEqualTo(1); + assertThat(exported.report().bySubject()).doesNotContainKey("SectionNode"); + // The paragraph Word keeps between the two tables goes with the second, and is named. + assertThat(exported.report().bySubject().get("space above")).singleElement() + .satisfies(note -> assertThat(note.detail()).doesNotContain("border")); + } + + @Test + void theSpaceAboveACardTakesTheHangOfTheBlockAboveBeforeItsBorder() throws Exception { + // Half a point more space than the line above hangs: the hang takes it first, and the + // card's padding holds what its top border then reaches past it; nothing is named. + long down = reachBelow(hungOverACard(10), "Iconed"); + double gap = down / 20.0 + 0.5; + Exported exported = hungOverACard(gap); + + assertThat(reachBelow(exported, "Iconed")).as("the same line").isEqualTo(down); + assertThat(exported.report().bySubject()).doesNotContainKey("space above").doesNotContainKey("SectionNode"); + } + + /** A contact stack whose last line hangs, then a card ruled above, padded 4pt, {@code gap} below it. */ + private static Exported hungOverACard(double gap) throws Exception { + return export(page -> page.spacing(gap).addSection("Contact", DocxPanelTailTest::contact) + .addSection("Card", card -> card.fillColor(SURFACE).borders(DocumentBorders.top(RULE)) + .padding(DocumentInsets.of(4)).addParagraph("Inside"))); + } + + @Test + void aHangATableBelowDoesNotTakeIsNamedOnTheTable() throws Exception { + Exported exported = export(page -> page.addSection("Card", card -> { + card.fillColor(SURFACE); + contact(card); + }).addTable(this::first)); + + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("First"); + assertThat(note.detail()).contains("the line hanging below the block above it (") + .contains("the paragraph Word keeps between two tables (0.1pt)"); + }); + } + + @Test + void aParagraphPulledUpStandsBelowNoBorder() throws Exception { + // An edge below zero pulls a paragraph up, as TealPulse's contact pairs are in their + // strip: it is no border below a panel, and nothing is named for it. + Exported exported = export(page -> page.addParagraph("Above") + .addParagraph(p -> p.text("Pulled").margin(new DocumentInsets(-4, 0, 0, 0))) + .addRow(row -> row.addParagraph(p -> p.text("Lifted").margin(new DocumentInsets(-4, 0, 0, 0))) + .addParagraph("Beside")) + .addParagraph("Below")); + + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + } + + @Test + void twoTouchingTablesNameTheParagraphBetweenThem() throws Exception { + // Word merges two tables with nothing between them, so a paragraph a tenth of a point + // tall keeps them apart, and stands the second that much lower. + Exported exported = export(page -> page.addTable(this::first).addTable(this::second)); + + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("Second"); + assertThat(note.detail()).isEqualTo("it stands 0.1pt lower than the page sets it, and what follows with it: " + + "the space the page leaves above it does not hold the paragraph Word keeps " + + "between two tables (0.1pt)"); + }); + } + + @Test + void twoTablesWithSpaceBetweenThemNameNothing() throws Exception { + // The paragraph between them takes its tenth of a point out of the space. + Exported exported = export(page -> page.spacing(4).addTable(this::first).addTable(this::second)); + XWPFParagraph between = (XWPFParagraph) exported.document().getBodyElements().get(1); + CTSpacing spacing = between.getCTP().getPPr().getSpacing(); + + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + assertThat(DocxTwips.of(spacing.getLine())).as("a tenth of a point").isEqualTo(2); + assertThat(before(between) + DocxTwips.of(spacing.getAfter() == null ? 0 : spacing.getAfter())) + .as("the 4pt, less that tenth").isEqualTo(4 * 20 - 2); + } + + private void first(com.demcha.compose.document.dsl.TableBuilder table) { + table.name("First").columns(DocumentTableColumn.fixed(100)).rowCells(DocumentTableCell.text("A")); + } + + private void second(com.demcha.compose.document.dsl.TableBuilder table) { + table.name("Second").columns(DocumentTableColumn.fixed(100)).rowCells(DocumentTableCell.text("B")); + } + + /** A contact stack whose last line holds an icon lowered below the page's line. */ + private static void contact(SectionBuilder section) { + section.spacing(3); + section.addParagraph(p -> p.textStyle(SMALL).text("London")); + section.addParagraph(p -> p.name("Iconed").textStyle(SMALL).inlineText("GitHub ", SMALL) + .inlineSvgIcon(ICON, 10.5, InlineImageAlignment.CENTER, -1.35, null)); + } + + /** Twips as the report states points: to a hundredth, no trailing zeros. */ + private static String points(long twips) { + return java.math.BigDecimal.valueOf(Math.round(twips / 20.0 * 100) / 100.0).stripTrailingZeros().toPlainString(); + } + + /** + * How far a line held to its icon reaches below the page's line, in twips: the exact line Word + * holds it to, less the page's line, less what of the 3pt gap above it the line starts above + * the paragraph's top (the space above it written that much shorter). + */ + private static long reachBelow(Exported exported, String name) { + // The icon's line, in the body or in the first panel's cell. + List paragraphs = new java.util.ArrayList<>(exported.document().getParagraphs()); + exported.document().getTables().forEach(table -> paragraphs.addAll(table.getRow(0).getCell(0).getParagraphs())); + XWPFParagraph iconed = paragraphs.stream().filter(p -> p.getText().startsWith("GitHub")).findFirst().orElseThrow(); + CTSpacing spacing = iconed.getCTP().getPPr().getSpacing(); + long up = 3 * 20 - (spacing.isSetBefore() ? DocxTwips.of(spacing.getBefore()) : 0); + return DocxTwips.of(spacing.getLine()) - up - Math.round(exported.heights().get(name) * 20); + } + + private static XWPFTableCell panel(Exported exported) { + return exported.document().getTables().get(0).getRow(0).getCell(0); + } + + private static long topMargin(XWPFTableCell cell) { + return DocxTwips.of(cell.getCTTc().getTcPr().getTcMar().getTop().getW()); + } + + private static long bottomMargin(XWPFTableCell cell) { + return DocxTwips.of(cell.getCTTc().getTcPr().getTcMar().getBottom().getW()); + } + + private static XWPFParagraph paragraph(Exported exported, String text) { + return exported.document().getParagraphs().stream().filter(p -> p.getText().equals(text)).findFirst().orElseThrow(); + } + + private static long before(XWPFParagraph paragraph) { + CTSpacing spacing = paragraph.getCTP().getPPr() == null ? null : paragraph.getCTP().getPPr().getSpacing(); + return spacing == null || !spacing.isSetBefore() ? 0 : DocxTwips.of(spacing.getBefore()); + } + + /** The export, its report, and each named node's height and first page as the layout places it. */ + private record Exported(XWPFDocument document, DocxExportReport report, java.util.Map heights, + java.util.Map pages) { + } + + private static Exported export(Consumer content) throws Exception { + AtomicReference report = new AtomicReference<>(); + java.util.Map heights = new java.util.HashMap<>(); + java.util.Map pages = new java.util.HashMap<>(); + byte[] docx; + try (DocumentSession session = GraphCompose.document().pageSize(400, 600).margin(DocumentInsets.of(20)).create()) { + session.pageFlow(content::accept); + session.layoutGraph().nodes().forEach(node -> { + if (node.semanticName() != null) { + heights.putIfAbsent(node.semanticName(), node.placementHeight()); + pages.putIfAbsent(node.semanticName(), node.startPage()); + } + }); + docx = session.export(new DocxSemanticBackend(report::set)); + } + return new Exported(new XWPFDocument(new ByteArrayInputStream(docx)), report.get(), heights, pages); + } +} diff --git a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxRowPaintTest.java b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxRowPaintTest.java index 84db7aa57..cf8727b48 100644 --- a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxRowPaintTest.java +++ b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxRowPaintTest.java @@ -106,31 +106,38 @@ void anOutlineAndASidesBorderAreItsPanelsBorders() throws Exception { CTTcBorders outlined = panelCell(outlinedRow).getCTTc().getTcPr().getTcBorders(); assertThat(List.of(outlined.getTop(), outlined.getLeft(), outlined.getBottom(), outlined.getRight())) .allSatisfy(side -> assertThat(side.xgetColor().getStringValue()).isEqualToIgnoringCase("1A5694")); - // Word draws the borders above and below outside the row, where the page takes no room, - // and with no padding to take the top one, starts the columns below it. + // Word sets the columns below the whole border above, where the page strokes it on the + // row's edge: with no padding and no space above to take what reaches past the row's box, + // the columns stand that much lower. assertThat(outlinedRow.report().bySubject().get("RowNode")).singleElement().satisfies(note -> { assertThat(note.severity()).isEqualTo(DocxExportReport.Severity.APPROXIMATED); assertThat(note.path()).contains("Outlined"); - assertThat(note.detail()).isEqualTo("written as a panel; its borders above and below are drawn outside " - + "the panel's row in Word: where no space round the row takes them, " - + "what follows stands up to 2pt lower than the page sets it; its " - + "columns stand up to 1pt lower than the page sets them, where neither " - + "its padding nor the space above it takes its top border"); + assertThat(note.detail()).isEqualTo("its content stands 1pt lower than the page sets it, and what follows " + + "up to as much: Word sets it below the whole of its top border, and " + + "neither the space above it nor its padding takes what of the border " + + "reaches past the panel's box"); }); Exported padded = export(page -> page.addRow(row -> row.stroke(RULE).padding(DocumentInsets.of(4)) .addParagraph("Left").addParagraph("Right"))); - assertThat(padded.report().bySubject().get("RowNode")).extracting(DocxExportReport.Note::detail) - .as("its padding takes its top border").singleElement().asString().doesNotContain("its columns"); + assertThat(padded.report().bySubject()).as("its padding takes its top border").doesNotContainKey("RowNode"); + // The border below reaches past the row's box too: the block below stands that much lower + // where neither the space between them nor the row's padding takes it, and says so. Exported underlined = export(page -> page.addRow(row -> row.borders(DocumentBorders.bottom(RULE)) - .addParagraph("Left").addParagraph("Right"))); + .addParagraph("Left").addParagraph("Right")).addParagraph("After")); CTTcBorders bottom = panelCell(underlined).getCTTc().getTcPr().getTcBorders(); assertThat(bottom.getBottom().xgetColor().getStringValue()).isEqualToIgnoringCase("1A5694"); assertThat(bottom.isSetTop() && bottom.getTop().getVal() != STBorder.NONE && bottom.getTop().getVal() != STBorder.NIL) .as("no top border").isFalse(); - assertThat(underlined.report().bySubject()).doesNotContainKey("row paint"); - assertThat(underlined.report().bySubject().get("RowNode")).extracting(DocxExportReport.Note::detail) - .singleElement().asString().endsWith("up to 1pt lower than the page sets it"); + assertThat(underlined.report().bySubject()).doesNotContainKey("row paint").doesNotContainKey("RowNode"); + assertThat(underlined.report().bySubject().get("space above")).singleElement() + .extracting(DocxExportReport.Note::detail).isEqualTo("it stands 1pt lower than the page sets it, and " + + "what follows with it: the space the page leaves above it does not hold the border Word draws " + + "past the box of the panel above it (1pt)"); + Exported spaced = export(page -> page.addRow(row -> row.borders(DocumentBorders.bottom(RULE)) + .addParagraph("Left").addParagraph("Right")).addParagraph(p -> p.text("After") + .margin(new DocumentInsets(4, 0, 0, 0)))); + assertThat(spaced.report().bySubject()).as("the space between them takes it").doesNotContainKey("space above"); } @Test From 494fa97e4f199faf9e1a74825e80bda6fa80e7f0 Mon Sep 17 00:00:00 2001 From: DemchaAV Date: Thu, 8 Oct 2026 13:53:37 +0100 Subject: [PATCH 2/3] fix(docx): name a pull nothing gives, and take a cell's last border where its writer knows the room - A pull out of the block above - a negative bottom margin, a panel's as a paragraph's - comes out of the space below it before any tail, the space above a table included; what that space and the next block's own top edge do not give stands the next block lower and is named ("space above"). - A cell no longer carries the border of the card ending it into the flow; the cell's writer decides. A row takes it, with the cell's hanging line, out of the room under that cell, then the card's padding; a panel takes it out of the card's padding, then its own; a table's composed cell and a column of side-by-side layers take it out of the card's padding and name the rest, up to that much where a cell beside it may hold it. - A container leaves no room under its content: what its content leaves below itself comes out of its padding directly. - A panel the layout moves to a new page holds the space above it there, as a table does. Fidelity baselines (Word, LibreOffice on Windows) rewritten: invoice-subscription stands nearer the page than with the previous commit. --- CHANGELOG.md | 90 ++--- .../architecture/backend-capability-matrix.md | 2 +- docs/recipes/docx-export.md | 50 +-- .../libreoffice-windows-lines.tsv | 68 ++-- .../docx-fidelity/libreoffice-windows.tsv | 2 +- .../docx-fidelity/word-windows-lines.tsv | 44 +-- .../resources/docx-fidelity/word-windows.tsv | 2 +- render-docx/README.md | 4 + .../semantic/docx/DocxSemanticBackend.java | 208 +++++++---- .../docx/DocxNodeFieldLedgerTest.java | 22 +- .../semantic/docx/DocxPanelHeightTest.java | 2 +- .../semantic/docx/DocxPanelTailTest.java | 333 +++++++++++++++--- 12 files changed, 580 insertions(+), 247 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0e620104..2dc43a84a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,34 +20,44 @@ follow semantic versioning; release dates are ISO 8601. the panel's edge and its content where the page sets it; above, then, the room over its first line. What none of them takes is named: on the panel for its top border, as a row's was, and on the block that stands lower for its bottom one (`space above`). - - **The height held is the content's.** Word and LibreOffice read a panel's written row height - as its content's, its margins and both borders round it: held a point above its content's - height, an outlined card padded 4pt stood a point taller than the page's. A panel holds the + - **The height held is the content's.** Word and LibreOffice on Windows read a panel's written + row height as its content's, with its margins and both borders round it: held a point above + its content's height, an outlined card padded 4pt stood a point taller. A panel holds the page's height less its padding, and less what the room over its first line gave its top - border. A shape container, its layers centred in it, holds its outline's height less both - its borders and its margins, which keep inside it, and nothing of them is named; a padded - outlined one was held one border less only. - - **What a panel's content leaves below itself** past where the page ends it — a last line held - to an icon, the border of a card ending the panel — comes out of the room the page leaves - under that content, then out of the panel's padding below, then out of the space under the - panel; what none of them takes is named (`space above`). A card's border ending a row's cell - reaches past the row only by what the row's room under that cell does not hold. - - **The paragraph Word keeps between any two tables** — a tenth of a point, without which - Word merges them — is named on the second where the space between them does not take it - (`space above`), together with a border reaching it. - - Measured in Word 16 and LibreOffice alike on cards with 2pt borders — above, below and all - round — with no padding and with 1 and 4pt of it, with and without space round them, stacked - and in a row's columns, every line stood where the page sets it, or as much lower as the - report names: within 0.15pt in Word and 0.05pt in LibreOffice. In the DOCX fidelity corpus - 25 of the 62 documents change, and the report names 15 more notes: the tenth of a point - between two tables, 14 times, and `ObsidianInvoice`'s totals row, 0.72pt below a border - nothing takes. Twelve documents stand nearer the page in Word — the engineering cover - letter's median line from 1.27pt to 0.13pt — and eight further, `cv-panel`, - `invoice-subscription`, `cv-modern_professional` and `cv-classic_serif` most: there the - whole border taken out of the space had made up for other errors, a heading's baseline left - up to half a point from where Word seats it in an exact line, a spacer of no height written - as a tenth of a point, rounding to the twip inside a card. The fidelity baselines record both. + border, which came off it a second time. A shape container, its layers centred in it, holds + its outline's height less both borders and its margins, which keep inside it, and nothing of + them is named; a padded outlined one was held one border less only. + - **What a panel's content leaves below itself** — a last line held to an icon, the border of a + card ending the panel, which that card's padding takes first — comes out of the panel's + padding below, then out of the space under it; what neither takes is named (`space above`). + In a row's cell the line and the card's border reach past the row together, by what the + row's room under the cell does not hold. Ending a table's composed cell or a column of + side-by-side layers, whose content the layout does not measure against its row, the border + is named on the cell's content, its row up to that much taller, and the space below takes + none of it. + - **A pull** — a negative bottom margin, a panel's as a paragraph's — comes out of the space + below it and the next block's own top edge; what they cannot give stands that block lower + and is named (`space above`), where it was dropped unnamed. + - **The paragraph Word keeps between any two tables** — a tenth of a point, without which Word + merges them — is named on the second where the space between them does not take it, with + whatever else stands it lower; a container's top edge above a table counts as that space. + - **A panel the layout moves to a new page** keeps the space above it there, on a line of its + own, as a table does, and what the block above leaves below itself stays on the page above. + + Measured in Word 16 and LibreOffice on Windows — cards with 2pt borders above, below and all + round, with no padding and with 1 and 4pt of it, with and without space round them; cards + outlined at 0.5 and 2pt stacked, and at 0.5pt in a row's columns — every line stood where the page + sets it, or as much lower as the report names: within 0.15pt in Word and 0.05pt in + LibreOffice. + In the DOCX fidelity corpus 25 of the 62 documents change, and the report names 15 more + notes: the tenth of a point between two tables, 14 times, and `ObsidianInvoice`'s totals row, + 0.72pt lower for a 0.62pt border and that tenth of a point. Twelve documents stand nearer the + page in Word — the engineering cover letter's median line from 1.27pt to 0.13pt — and eight + further, `cv-panel`, `invoice-subscription`, `cv-modern_professional` and `cv-classic_serif` + most: where traced, the whole border taken out of the space had made up for other errors — a + heading's baseline left up to half a point from where Word seats it in an exact line, a spacer + of no height written as a tenth of a point, rounding to the twip inside a card, a step between + a table's header and its first row. The fidelity baselines record both. - **A DOCX export writes a row's fill, outline and side borders, as a panel holding its columns.** A row paints its box as a container does — `RowBuilder.fillColor`, `stroke`, @@ -1110,21 +1120,19 @@ follow semantic versioning; release dates are ISO 8601. the heavier border, which LibreOffice was taken to add to it once. Both editors draw the cell's top and bottom borders outside that height: a 9.2pt chip outlined with a 1.125pt border stood 10.3pt tall in Word and 10.2pt in LibreOffice, and each staff row holding one stood 1.1pt - taller than the page's; the rota's last row stood 6.5pt low in Word, now 2.4. Where its padding - does not hold the top border, the row now holds the outline's height less the borders drawn - outside it — the top as far as no space above took it — as a panel with a placement already - did. `CobaltRota`'s p90 drift falls from 6.4pt to 2.9 in Word and from 7.3pt to 3.9 - in LibreOffice. + taller than the page's; the rota's last row stood 6.5pt low in Word, now 2.4. The row now + holds the outline's height less both borders and its margins, which keep inside it (see the + entry on what follows a panel). `CobaltRota`'s p90 drift falls from 6.4pt to 2.9 in Word and + from 7.3pt to 3.9 in LibreOffice. - **`MerchantInvoice` fits its page in Word again.** Two things pushed its footer row onto a second page. - Its payment panel opens a table cell, so no space above could take the panel's 0.875pt top border, which Word draws above a cell's content. Every line inside stood that much - low, and the row that much taller. A panel with less space above it than its top border now - takes what of the border neither that space nor its padding holds out of the space above - its first line, where that line has some; where its row holds the page's height, that - height is less the borders Word draws outside it. LibreOffice, where the panel's content - sets its height, draws `MerchantInvoice`'s panel that border's width shorter. + low, and the row that much taller. What of the border reaches past the panel's box and + neither that space nor its padding takes now comes out of the space above its first line, + where that line has some, and the content's height the panel holds is that much less (see + the entry on what follows a panel). - Its footer reaches 9.8pt from the page's edge, past the page's 3.4pt margin, and Word moved the body clear of it. A band alone of its kind reaching past the margin, by any more than a twentieth of a point, now writes that margin @@ -1423,10 +1431,10 @@ follow semantic versioning; release dates are ISO 8601. "MW". Written apart, the letters stood in the flow and the badge where the page puts it: `ObsidianInvoice`'s footer "K" sat below its disc's corner, its party discs were hidden behind their letters under the panel's shading, and the monogram tile's letter left it for - the next page. A panel's top border now comes out of the space above it, and its bottom - border out of its bottom margin or, past that, out of the space above whatever follows: Word - draws them outside the cell's shading, where the page strokes them on the panel's edge, so - every outlined card stood its borders lower and `ObsidianInvoice`'s line items sat 1.6pt low. In Word, `ObsidianInvoice`'s line items land + the next page. What of a panel's borders above and below Word draws past its box now comes + out of the space round it (see the entry on what follows a panel): every outlined card had + stood that much lower, and `ObsidianInvoice`'s line items sat 1.6pt low. In Word, + `ObsidianInvoice`'s line items land within 0.2pt of the page, `ProfessionalSidebar`'s p90 drift falls from 78.8pt to 1.3, and `NorthlineProposal`'s cover header, which stood 12pt high, lands on the page's. - **Icons inside painted panels show in Word, beside the text they belong to.** A shape drawn diff --git a/docs/architecture/backend-capability-matrix.md b/docs/architecture/backend-capability-matrix.md index c24d35c5d..6604db341 100644 --- a/docs/architecture/backend-capability-matrix.md +++ b/docs/architecture/backend-capability-matrix.md @@ -70,7 +70,7 @@ Payload records live in `core` under | Inline vector shapes (`ParagraphShapeSpan`) | ✅ `PdfParagraphFragmentRenderHandler` | ⚠️ `PptxParagraphFragmentRenderHandler` + `PptxInlineGeometry` (distinct per-corner radii render with the top-left radius — single-adjust preset) | ⚠️ `DocxSemanticBackend.writeInlinePicture` + `DocxShapePictures` (a transparent PNG drawn by the shared `InlineSvgRasters` from the outline, fill and stroke — every outline kind, each layer centred in the run's box — placed as an inline picture is; the picture takes as far as the stroked ink reaches past the outline — half the stroke on an edge, more at a sharp corner's miter — and a pixel on each side, measured side by side, and is lowered by what it takes below, so no edge is cut and a shape takes that much more room in the line; a list marker that draws a disc is its picture; at the top level of a `hangingIndent(true)` list that does not nest it is followed by a tab to where the layout starts the item's text, the item's lines hanging there, when the picture clears that stop, else by a space) | | Inline SVG (`ParagraphSvgSpan`) | ✅ `PdfParagraphFragmentRenderHandler` + `PdfPathPainter` | ⚠️ `PptxParagraphFragmentRenderHandler` + `PptxInlineGeometry` + `PptxInlineSvgRasterizer` (simple layers stay native; arbitrary clips, exact dash/cap/join styles, and off-viewBox art use a transparent PNG fallback — drawn by the shared `InlineSvgRasters`; gradient paints use their primary colour) | ⚠️ `DocxSemanticBackend.writeInlinePicture` (always the transparent PNG: the same layers the layout resolves, through `InlineSvgLayers`, drawn by the raster the PPTX fallback uses — `InlineSvgRasters`, four pixels a point — and placed as an inline picture is; emoji included, so an emoji is a picture rather than a character, reported `APPROXIMATED`) | | Text an inline icon stands for — copy, search, extraction (`ParagraphSvgSpan.text`, set by `SvgIcon.withText` and on every `EmojiLibrary` emoji) | ✅ `PdfTextLayer` via `PdfRenderEnvironment.writeTextLayer`: one invisible glyph over the icon on the line's baseline, from a Type 3 font of empty glyphs whose `ToUnicode` states each text, a whole ZWJ sequence included; rendering mode 3, so nothing is painted. One font per document, a new one after 255 distinct texts; a text over 256 UTF-16 units is not written. A block icon (`addSvgIcon`, `SvgIcon.node`) writes no text. `ActualText` around the paths was measured to reach none of PDFBox, poppler, pdf.js and MuPDF — it replaces glyphs, and a drawing has none. In a right-to-left line the glyph sits between the words it was written between and states its whole text; reading such a line back, PDFBox reverses the emoji one UTF-16 unit at a time and poppler reverses the code points of a ZWJ sequence or a U+FE0F pair, while pdf.js and MuPDF keep it whole (measured; a reader-side reversal of the glyph's text) | ❌ the icon is drawn and its text is not written | ⚠️ the icon is a picture whose description (`docPr/@descr`) is its text — read by a screen reader, but not a character a reader copies or searches | -| Rectangle shape — fill, stroke, per-corner radii, side borders (`ShapeFragmentPayload`) | ✅ `PdfShapeFragmentRenderHandler` | ⚠️ `PptxShapeFragmentRenderHandler` (distinct per-corner radii render with the top-left radius on all corners — single-adjust `roundRect` preset — until custom geometry lands; uniform radii and side borders exact) | ⚠️ `DocxSemanticBackend.writeContainerChildren` — a `SectionNode` or `ContainerNode` carrying a fill, per-side borders or a uniform stroke is written as a one-cell table, and so is a `RowNode` in the flow that paints its box (`writePaintedRow`, through the same `writePanelPiece`), its columns a table nested in the cell without its padding — not in a band of layers or a stack's measured column, with a padding or margin it cannot hold, composed in a table cell or in a page zone, where it is its columns alone and its paint is reported: the cell's shading is the fill behind everything inside, its borders are the container's at its full height, and its margins are the padding on all four sides, less half of each border, with the table half a border wider on each side, so the text and the border land where the page draws them — in the body, the left margin is the whole padding, the table no wider on that side, and its indent places its text, as Word 16 and LibreOffice on Windows centre a body table's left border on its edge (an older LibreOffice, the Linux CI's, reads the indent as the table's edge and sets the text about a padding right). Word sets a cell's content its whole top border and its margin inside the row, and ends the row its margin and its whole bottom border past the content, so half of each border — and as much of its inner half as the padding falls short of it — reaches past the panel: the space round it takes that first, then its padding, the border then drawn that much inside the panel's edge, then, above, the room over its first line; what none of them takes is reported (`space above` on the block below, the panel's kind for its top border). What its content leaves below itself past where the page ends it — a last line held to an icon, a card's border ending it — comes out of the room the page leaves under that content and then out of its padding below first, the same way; and the tenth of a point of the paragraph between any two tables, where the space between them does not take it, is reported too. A shape container's borders stay inside its outline. A panel the layout measures holds the page's height less its padding as its row's height, which Word and LibreOffice read as its content's, its margins and borders round it; a shape container holds its outline's, less its borders and margins. The table takes the width the layout placed the container at, plus a point of editor slack; in a cell, a panel whose left border hangs half its width left of the cell's text gives up what runs past the cell's edge as Word starts it, half that border in — no more than its left side had given its text, the half border the table is wider by and what its left margin gave back of the other half —, since a nested table running past its cell widens the cell, fixed layout or not. A `keepTogether()` panel the layout held on one page is a row that may not split. Panels, rows and tables inside it are tables in its cell; a table cell no style fills is written white, as the page draws it. One deviation: the corner radius is dropped (a cell is rectangular) with one warning per export. A translucent fill is flattened against what Word paints under the panel: the panel or cell around it as written, or on the page the colour the layout paints there (`DocxLayoutMetrics.colourUnder`: the fills drawn before it, at its centre, a page background included and a row's own fill left out, what stands on it being written in the row's panel, on its shading). A translucent border is flattened against the panel's fill where it has one, since a cell's shading and borders are opaque; each is named in the report as `translucency`. An unpainted container is not a table: its paragraphs are indented by every enclosing margin and padding, and its rows and tables get `w:tblInd`. A standalone `ShapeNode` that is only a fill, with no stroke, radius, gradient or transform, and no taller than Word's thickest border (12pt) — an `addDivider` — is a rule, written as a line's is; any other `ShapeNode`, standalone or laid over others, is drawn by `DocxDrawings` as a floating DrawingML shape behind the text, where the layout placed it — `rect`, or `roundRect` with the largest corner radius, in its fill and outline colours with their alpha, each side border a line along its edge; a gradient paint and a transform are not carried, nor are a link, an outline entry or an anchor's bookmark — each named in the shape's report note, as unequal corners are —, and a shape with neither a fill colour nor an outline is dropped and reported. It is anchored in the paragraph whose text it stands beside, placed down from its top, so it moves with that text when the text above is edited; beside no text, in a body paragraph on its page (a table cell's only on a page with no other, reported), where it stays — except a drawing that is all a table cell holds, an icon beside its label (in a row of the flow, a layer stack or shape container that only draws, with no margins, on one page and painting nothing outside its box; in a composed cell, a layer stack of shapes with no margin or padding, the only drawing the cell holds, matched to the table's fragments inside the cell by kind and size), which is anchored in that cell's paragraph, held at its height and placed from its top and the cell's text column, so it moves with its row; a drawing holding a line stays on the page —, and is drawn in front of the text inside a filled panel unless it frames text or a picture there; reported `APPROXIMATED` | +| Rectangle shape — fill, stroke, per-corner radii, side borders (`ShapeFragmentPayload`) | ✅ `PdfShapeFragmentRenderHandler` | ⚠️ `PptxShapeFragmentRenderHandler` (distinct per-corner radii render with the top-left radius on all corners — single-adjust `roundRect` preset — until custom geometry lands; uniform radii and side borders exact) | ⚠️ `DocxSemanticBackend.writeContainerChildren` — a `SectionNode` or `ContainerNode` carrying a fill, per-side borders or a uniform stroke is written as a one-cell table, and so is a `RowNode` in the flow that paints its box (`writePaintedRow`, through the same `writePanelPiece`), its columns a table nested in the cell without its padding — not in a band of layers or a stack's measured column, with a padding or margin it cannot hold, composed in a table cell or in a page zone, where it is its columns alone and its paint is reported: the cell's shading is the fill behind everything inside, its borders are the container's at its full height, and its margins are the padding on all four sides, less half of each border, with the table half a border wider on each side, so the text and the border land where the page draws them — in the body, the left margin is the whole padding, the table no wider on that side, and its indent places its text, as Word 16 and LibreOffice on Windows centre a body table's left border on its edge (an older LibreOffice, the Linux CI's, reads the indent as the table's edge and sets the text about a padding right). Word sets a cell's content its whole top border and its margin inside the row, and ends the row its margin and its whole bottom border past the content, so half of each border — and as much of its inner half as the padding falls short of it — reaches past the panel: the space round it takes that first, then its padding, the border then drawn that much inside the panel's edge, then, above, the room over its first line; what none of them takes is reported (`space above` on the block below, the panel's kind for its top border). What its content leaves below itself past where the page ends it — a last line held to an icon, a card's border ending it, which that card's padding takes first — comes out of its padding below first, the same way; a card's border ending a row's cell reaches past the row only by what the row's room under that cell does not hold, and one ending a table's composed cell is reported on the card, its row up to that much taller. A negative bottom margin pulls what follows up out of the space between them, and what that space cannot give is reported, as is the tenth of a point of the paragraph between any two tables where the space between them does not take it. A shape container's borders stay inside its outline. A panel the layout measures holds the page's height less its padding as its row's height, which Word and LibreOffice on Windows read as its content's, its margins and borders round it; a shape container holds its outline's, less its borders and margins. The table takes the width the layout placed the container at, plus a point of editor slack; in a cell, a panel whose left border hangs half its width left of the cell's text gives up what runs past the cell's edge as Word starts it, half that border in — no more than its left side had given its text, the half border the table is wider by and what its left margin gave back of the other half —, since a nested table running past its cell widens the cell, fixed layout or not. A `keepTogether()` panel the layout held on one page is a row that may not split. Panels, rows and tables inside it are tables in its cell; a table cell no style fills is written white, as the page draws it. One deviation: the corner radius is dropped (a cell is rectangular) with one warning per export. A translucent fill is flattened against what Word paints under the panel: the panel or cell around it as written, or on the page the colour the layout paints there (`DocxLayoutMetrics.colourUnder`: the fills drawn before it, at its centre, a page background included and a row's own fill left out, what stands on it being written in the row's panel, on its shading). A translucent border is flattened against the panel's fill where it has one, since a cell's shading and borders are opaque; each is named in the report as `translucency`. An unpainted container is not a table: its paragraphs are indented by every enclosing margin and padding, and its rows and tables get `w:tblInd`. A standalone `ShapeNode` that is only a fill, with no stroke, radius, gradient or transform, and no taller than Word's thickest border (12pt) — an `addDivider` — is a rule, written as a line's is; any other `ShapeNode`, standalone or laid over others, is drawn by `DocxDrawings` as a floating DrawingML shape behind the text, where the layout placed it — `rect`, or `roundRect` with the largest corner radius, in its fill and outline colours with their alpha, each side border a line along its edge; a gradient paint and a transform are not carried, nor are a link, an outline entry or an anchor's bookmark — each named in the shape's report note, as unequal corners are —, and a shape with neither a fill colour nor an outline is dropped and reported. It is anchored in the paragraph whose text it stands beside, placed down from its top, so it moves with that text when the text above is edited; beside no text, in a body paragraph on its page (a table cell's only on a page with no other, reported), where it stays — except a drawing that is all a table cell holds, an icon beside its label (in a row of the flow, a layer stack or shape container that only draws, with no margins, on one page and painting nothing outside its box; in a composed cell, a layer stack of shapes with no margin or padding, the only drawing the cell holds, matched to the table's fragments inside the cell by kind and size), which is anchored in that cell's paragraph, held at its height and placed from its top and the cell's text column, so it moves with its row; a drawing holding a line stays on the page —, and is drawn in front of the text inside a filled panel unless it frames text or a picture there; reported `APPROXIMATED` | | Ellipse (`EllipseFragmentPayload`) | ✅ `PdfEllipseFragmentRenderHandler` | ✅ `PptxEllipseFragmentRenderHandler` | ⚠️ `DocxDrawings` — an `ellipse` shape anchored as a rectangle is; a shape container's elliptical outline is drawn the same way, and a picture that fills the container it clips takes the ellipse as its geometry; a transform is not carried, nor a link, an outline entry or an anchor's bookmark (each named in the ellipse's report note), and a shape in a filled panel is drawn in front of the text, over the cell's shading, unless it frames text or a picture; a shape is anchored as a rectangle is — except, as for a rectangle, a drawing that is all a table cell holds — in a row of the flow, a badge alone beside its text — which is anchored in that cell and moves with its row | | Line — dash pattern, line cap (`LineFragmentPayload`) | ✅ `PdfLineFragmentRenderHandler` | ⚠️ `PptxLineFragmentRenderHandler` (numeric dash arrays map to the generic dashed preset; solid lines and caps exact) | ⚠️ `DocxSemanticBackend.writeRule` — a horizontal line with no transform is Word's own rule: an empty paragraph whose bottom border is the stroke (colour, thickness in eighths of a point, clamped to Word's 12pt), its ends as the paragraph's indents and the space above and below the stroke in its box as the paragraph's height and the space owed below it; a dash pattern becomes Word's dashed or dotted border, reported `APPROXIMATED`; a translucent stroke is flattened against the colour the page paints under it, a page background included, reported as `translucency`; the line cap and a link are not carried (both reported, a link as `rule link`; an outline entry on it is reported too). A vertical or slanted line, and a line laid over others in a layer stack, canvas or shape container — a line among the text of a layer stack of one layer excepted, which is a rule —, is drawn by `DocxDrawings` as a `line` shape anchored as a rectangle is — the dash pattern, cap and a transform are not carried, nor a link, an outline entry or an anchor's bookmark (each named in the line's report note); a line in a page zone is dropped and reported | | Polygon (`PolygonFragmentPayload`) | ✅ `PdfPolygonFragmentRenderHandler` | ✅ `PptxPolygonFragmentRenderHandler` + `PptxInlineGeometry` | ⚠️ `DocxDrawings` + `DocxCustomGeometry` — `a:custGeom`, the vertex ring closed, anchored as a rectangle is | diff --git a/docs/recipes/docx-export.md b/docs/recipes/docx-export.md index b22ecaf41..abb57eff4 100644 --- a/docs/recipes/docx-export.md +++ b/docs/recipes/docx-export.md @@ -233,13 +233,17 @@ move nothing. A negative bottom `margin` or `padding` — a paragraph's, an image's, a barcode's or a rule's — pulls the next paragraph up into it the same way: it comes out of the space above that -paragraph, its own top edge included, even where the two stand in different containers. What -that space cannot give is not written. Before a table, a page break or the end of a cell it -comes out of the space owed below instead. Layers that overlap on the page take none of it +paragraph, its own top edge included, even where the two stand in different containers, and +so does a panel's negative bottom `margin`. What that space cannot give stands the paragraph +lower — Word sets no block over another — and is named (`space above`). Before a table it +comes out of the space above the table the same way; before a page break or the end of a cell, +out of the space owed below instead. Layers that overlap on the page take none of it from one another, as the space between them is measured from their boxes. Text that runs past the foot of the block it stands in — a stack's or a shape container's last line, a row cell's icon line — comes out of the space above what follows the same way, a stack written as a band -included. +included, and what that space cannot give is named (`space above`); a painted panel's last +line comes out of its padding below first, and a shape container keeps its last line inside +its outline. A paragraph's or a list's `lineSpacing` — the gap the page puts between two wrapped lines — goes into the line: Word has one line height for a paragraph and no gap between its lines, @@ -529,18 +533,22 @@ How it lands: content, or the block below, that much lower, and the report names it: on the panel for its top border, on the block below for its bottom one (`space above`). A shape container's borders, its layers centred in it, stay inside its outline. Measured in Word 16 and - LibreOffice alike on 2pt borders with no padding and with 1 and 4pt of it, every line stood - where the page sets it, or as much lower as the report names: within 0.15pt in Word and - 0.05pt in LibreOffice. -- **Height.** Word and LibreOffice read a panel's row's written height as its content's, its - margins and both borders round it, so a panel the layout measures is held to the page's - height less its padding, and a shape container to its outline's, less its borders and margins. + LibreOffice on Windows alike on 2pt borders with no padding and with 1 and 4pt of it, every + line stood where the page sets it, or as much lower as the report names: within 0.15pt in + Word and 0.05pt in LibreOffice. +- **Height.** Word and LibreOffice on Windows read a panel's row's written height as its + content's, its margins and both borders round it, so a panel the layout measures is held to + the page's height less its padding, and a shape container to its outline's, less its borders + and margins. - **What hangs below.** What a panel's content leaves below itself past where the page ends it - — a last line held to an icon, the border of a card ending the panel — comes out of the room - the page leaves under that content, then out of the panel's padding below, then out of the - space under the panel; the rest is named (`space above`). So is the tenth of a point of the - paragraph Word keeps between any two tables, which it would otherwise merge, where the space - between them does not take it. + — a last line held to an icon, the border of a card ending the panel, which that card's own + padding takes first — comes out of the panel's padding below, then out of the space under the + panel; the rest is named (`space above`). A card's border ending a row's cell reaches past the + row only by what the row's room under that cell does not hold; ending a table's composed cell, + whose content the layout does not measure against its row, it is named on the card, its row + standing up to that much lower. So is the tenth of a point of the paragraph Word keeps between + any two tables, which it would otherwise merge, where the space between them does not take + it. - **Indent.** In the body the table's `w:tblInd` places its cell's text, the padding in, and is written even when it is 0 — a panel bled to the paper's edge by a negative margin its padding takes back. Unwritten, Word 16 puts the table's edge on the margin and the text a @@ -559,8 +567,9 @@ How it lands: anywhere else. - **Page breaks.** Word breaks no page inside a table cell, so a page break among a panel's children closes the panel there and opens it again after the break. -- **Measured in LibreOffice.** Word has not been measured yet; where it places a nested - table differently, a panel inside a panel may sit a few points off. +- **Measured.** Cards stacked in a row's columns, panels nested in its table, stand where the + page sets them in Word 16 and LibreOffice on Windows; a panel inside a panel has not been + measured in Word, and may sit a few points off there. Not representable, and left undone rather than approximated: @@ -1011,9 +1020,10 @@ left or linked are written in the flow as before. A shape beside text in a panel that text's paragraph in the cell and laid out in the cell, placed from the cell's text column and the paragraph's top, which Word and LibreOffice both measure from the paragraph, nested or not; placed from the page's edges instead, Word measured a nested cell's shape from -the outer cell's top. Word sets a panel's content below its whole top border and ends its row past its whole -bottom border, where the page strokes both on the panel's edge; what of them reaches past the -panel's box is taken, or named, as "What a panel keeps and loses" says. The body's +the outer cell's top. Word sets a panel's content below its whole top border and ends its row past +its whole bottom border, where the page strokes both on the panel's edge; what +of them reaches past the panel's box is taken, or named, as "What a panel +keeps and loses" says. The body's shapes stand above the page backgrounds, which LibreOffice stacks together with them. Each of these limits is named in the report: - A transform is not carried: a rotated or scaled shape is drawn upright at its size, and so diff --git a/qa/src/test/resources/docx-fidelity/libreoffice-windows-lines.tsv b/qa/src/test/resources/docx-fidelity/libreoffice-windows-lines.tsv index 240a7a361..fad338999 100644 --- a/qa/src/test/resources/docx-fidelity/libreoffice-windows-lines.tsv +++ b/qa/src/test/resources/docx-fidelity/libreoffice-windows-lines.tsv @@ -3257,7 +3257,7 @@ invoice-subscription 0:78acb3cb907b 0.27 0.12 www.halstead.example invoice-subscription 0:f1c030eb4329 0.29 0.12 vatnogb418227603 invoice-subscription 0:77ead61b5875 0.29 0.09 invoiceno invoice-subscription 0:0b0c0ee24de8 0.26 0.74 hs-inv-2026-0417 -invoice-subscription 0:0b0c0ee24de8#1 0.68 0.88 hs-inv-2026-0417 +invoice-subscription 0:0b0c0ee24de8#1 0.63 0.88 hs-inv-2026-0417 invoice-subscription 0:8feaf8016bab 0.34 0.09 issuedate invoice-subscription 0:4d49cb78b810 0.32 0.62 27august2026 invoice-subscription 0:ac10f8c16320 0.39 0.09 duedate @@ -3281,26 +3281,26 @@ invoice-subscription 0:32e8369a9c4f 0.54 0.13 qty invoice-subscription 0:d1062d072acd 0.54 0.06 unitprice invoice-subscription 0:7c512b48ba8a 0.54 0.12 vat invoice-subscription 0:cf38d95c9c6b 0.54 0.05 amount -invoice-subscription 0:86705447c73d 0.83 0.12 halsteadworkspacepremium(10seats -invoice-subscription 0:0c8dc980db3f 0.83 0.18 £18.00 -invoice-subscription 0:dc934fe30a94 0.83 0.09 20% -invoice-subscription 0:dc934fe30a94#1 0.85 0.09 20% -invoice-subscription 0:dc934fe30a94#2 0.87 0.09 20% -invoice-subscription 0:dc934fe30a94#3 0.89 0.09 20% -invoice-subscription 0:dc934fe30a94#4 0.91 0.09 20% -invoice-subscription 0:629184210581 0.83 0.19 £180.00 -invoice-subscription 0:59df1d2b0f69 0.85 0.12 hostedplatformservices -invoice-subscription 0:44c1ce3394d2 0.85 0.16 £420.00 -invoice-subscription 0:44c1ce3394d2#1 0.85 0.16 £420.00 -invoice-subscription 0:217bada1d20f 0.87 0.12 analyticsprolicences(5seats) -invoice-subscription 0:599cd58953ce 0.87 0.20 £8.40 -invoice-subscription 0:756b8c62fe05 0.87 0.19 £42.00 -invoice-subscription 0:b055bcc305ed 0.89 0.12 prioritysupportplan -invoice-subscription 0:1077d7cede59 0.89 0.18 £275.00 -invoice-subscription 0:1077d7cede59#1 0.89 0.18 £275.00 -invoice-subscription 0:361537ef6a11 0.91 0.12 voiceadd-on(5seats) -invoice-subscription 0:8bf9ac7b27bd 0.91 0.19 £6.00 -invoice-subscription 0:893d7480f763 0.91 0.19 £30.00 +invoice-subscription 0:86705447c73d 0.53 0.12 halsteadworkspacepremium(10seats +invoice-subscription 0:0c8dc980db3f 0.53 0.18 £18.00 +invoice-subscription 0:dc934fe30a94 0.53 0.09 20% +invoice-subscription 0:dc934fe30a94#1 0.55 0.09 20% +invoice-subscription 0:dc934fe30a94#2 0.57 0.09 20% +invoice-subscription 0:dc934fe30a94#3 0.59 0.09 20% +invoice-subscription 0:dc934fe30a94#4 0.61 0.09 20% +invoice-subscription 0:629184210581 0.53 0.19 £180.00 +invoice-subscription 0:59df1d2b0f69 0.55 0.12 hostedplatformservices +invoice-subscription 0:44c1ce3394d2 0.55 0.16 £420.00 +invoice-subscription 0:44c1ce3394d2#1 0.55 0.16 £420.00 +invoice-subscription 0:217bada1d20f 0.57 0.12 analyticsprolicences(5seats) +invoice-subscription 0:599cd58953ce 0.57 0.20 £8.40 +invoice-subscription 0:756b8c62fe05 0.57 0.19 £42.00 +invoice-subscription 0:b055bcc305ed 0.59 0.12 prioritysupportplan +invoice-subscription 0:1077d7cede59 0.59 0.18 £275.00 +invoice-subscription 0:1077d7cede59#1 0.59 0.18 £275.00 +invoice-subscription 0:361537ef6a11 0.61 0.12 voiceadd-on(5seats) +invoice-subscription 0:8bf9ac7b27bd 0.61 0.19 £6.00 +invoice-subscription 0:893d7480f763 0.61 0.19 £30.00 invoice-subscription 0:ab5aa97074c4 0.80 0.12 notes invoice-subscription 0:4440ed73b83f 0.38 0.12 thisinvoicecoverssoftwaresubscri invoice-subscription 0:fffc319556fa 0.39 0.12 hostedservicesforthecurrentbilli @@ -3311,19 +3311,19 @@ invoice-subscription 0:14edcfc20351 0.62 0.44 £189.40 invoice-subscription 0:57a66d21eb1b 0.67 0.11 totaldue invoice-subscription 0:cf1b68cc49ef 0.74 0.94 £1,136.40 invoice-subscription 0:3c7ade679fdf 0.79 0.12 paymentdetails -invoice-subscription 0:56ed021beb35 0.72 0.54 beneficiary -invoice-subscription 0:0b85f3c8ed04 0.68 0.33 halsteadsoftwareltd -invoice-subscription 0:4381dc2ab142 0.72 0.77 bank -invoice-subscription 0:6d50b2dd724f 0.68 0.84 northgatebank -invoice-subscription 0:10aeacde20ff 0.72 0.83 sortcode -invoice-subscription 0:b19b1415ef9b 0.68 0.99 40-05-30 -invoice-subscription 0:f92a9c925024 0.72 0.94 accountnumber -invoice-subscription 0:ef797c8118f0 0.68 0.97 12345678 -invoice-subscription 0:52367a6622b1 0.72 0.86 reference -invoice-subscription 0:04f7247e8e99 0.72 0.12 pleaseincludetheinvoicenumberast -invoice-subscription 0:7c6ab37d83ef 0.76 0.09 thankyouforyourbusiness. -invoice-subscription 0:354ffeb2bbc3 0.72 0.09 paymentisdueby10september2026.if -invoice-subscription 0:7f7d98088133 0.73 0.09 foranyqueries,pleasecontactbilli +invoice-subscription 0:56ed021beb35 0.67 0.54 beneficiary +invoice-subscription 0:0b85f3c8ed04 0.63 0.33 halsteadsoftwareltd +invoice-subscription 0:4381dc2ab142 0.67 0.77 bank +invoice-subscription 0:6d50b2dd724f 0.63 0.84 northgatebank +invoice-subscription 0:10aeacde20ff 0.67 0.83 sortcode +invoice-subscription 0:b19b1415ef9b 0.63 0.99 40-05-30 +invoice-subscription 0:f92a9c925024 0.67 0.94 accountnumber +invoice-subscription 0:ef797c8118f0 0.63 0.97 12345678 +invoice-subscription 0:52367a6622b1 0.67 0.86 reference +invoice-subscription 0:04f7247e8e99 0.67 0.12 pleaseincludetheinvoicenumberast +invoice-subscription 0:7c6ab37d83ef 0.71 0.09 thankyouforyourbusiness. +invoice-subscription 0:354ffeb2bbc3 0.67 0.09 paymentisdueby10september2026.if +invoice-subscription 0:7f7d98088133 0.68 0.09 foranyqueries,pleasecontactbilli invoice-subscription 0:7b14b8d2c5c4 0.00 0.19 page1of1 invoice-workspace 0:07f15cde5b18 0.15 0.11 kestrel invoice-workspace 0:07f15cde5b18#1 -0.04 0.11 kestrel diff --git a/qa/src/test/resources/docx-fidelity/libreoffice-windows.tsv b/qa/src/test/resources/docx-fidelity/libreoffice-windows.tsv index 7fca37b0d..2adea2502 100644 --- a/qa/src/test/resources/docx-fidelity/libreoffice-windows.tsv +++ b/qa/src/test/resources/docx-fidelity/libreoffice-windows.tsv @@ -39,7 +39,7 @@ invoice-modern_long 2 2 162 162 0.20 0.27 0 invoice-obsidian 1 1 81 81 0.34 1.19 0 invoice-payments 1 1 104 104 0.09 0.23 0 invoice-platform 1 1 111 111 0.27 0.43 0 -invoice-subscription 1 1 81 81 0.62 0.87 0 +invoice-subscription 1 1 81 81 0.54 0.67 0 invoice-workspace 1 1 90 90 0.21 0.43 0 letter-blue_banner 1 1 10 10 0.42 0.46 0 letter-boxed_sections 1 1 10 10 0.29 0.33 0 diff --git a/qa/src/test/resources/docx-fidelity/word-windows-lines.tsv b/qa/src/test/resources/docx-fidelity/word-windows-lines.tsv index 4ee861699..15448d0be 100644 --- a/qa/src/test/resources/docx-fidelity/word-windows-lines.tsv +++ b/qa/src/test/resources/docx-fidelity/word-windows-lines.tsv @@ -3383,28 +3383,28 @@ invoice-subscription 0:32e8369a9c4f 0.60 0.04 qty invoice-subscription 0:d1062d072acd 0.60 0.01 unitprice invoice-subscription 0:7c512b48ba8a 0.60 0.08 vat invoice-subscription 0:cf38d95c9c6b 0.60 0.01 amount -invoice-subscription 0:86705447c73d 0.97 0.06 halsteadworkspacepremium(10seats -invoice-subscription 0:0c8dc980db3f 0.97 0.06 £18.00 -invoice-subscription 0:dc934fe30a94 0.97 0.11 20% -invoice-subscription 0:dc934fe30a94#1 0.92 0.11 20% -invoice-subscription 0:dc934fe30a94#2 1.01 0.11 20% -invoice-subscription 0:dc934fe30a94#3 0.96 0.11 20% -invoice-subscription 0:dc934fe30a94#4 1.03 0.11 20% -invoice-subscription 0:629184210581 0.97 0.10 £180.00 -invoice-subscription 0:59df1d2b0f69 0.92 0.06 hostedplatformservices -invoice-subscription 0:44c1ce3394d2 0.92 0.01 £420.00 -invoice-subscription 0:44c1ce3394d2#1 0.92 0.11 £420.00 -invoice-subscription 0:217bada1d20f 1.01 0.06 analyticsprolicences(5seats) -invoice-subscription 0:599cd58953ce 1.01 0.02 £8.40 -invoice-subscription 0:756b8c62fe05 1.01 0.16 £42.00 -invoice-subscription 0:b055bcc305ed 0.96 0.06 prioritysupportplan -invoice-subscription 0:1077d7cede59 0.96 0.09 £275.00 -invoice-subscription 0:1077d7cede59#1 0.96 0.19 £275.00 -invoice-subscription 0:361537ef6a11 1.03 0.06 voiceadd-on(5seats) -invoice-subscription 0:8bf9ac7b27bd 1.03 0.12 £6.00 -invoice-subscription 0:893d7480f763 1.03 0.18 £30.00 +invoice-subscription 0:86705447c73d 0.61 0.06 halsteadworkspacepremium(10seats +invoice-subscription 0:0c8dc980db3f 0.61 0.06 £18.00 +invoice-subscription 0:dc934fe30a94 0.61 0.11 20% +invoice-subscription 0:dc934fe30a94#1 0.68 0.11 20% +invoice-subscription 0:dc934fe30a94#2 0.65 0.11 20% +invoice-subscription 0:dc934fe30a94#3 0.72 0.11 20% +invoice-subscription 0:dc934fe30a94#4 0.67 0.11 20% +invoice-subscription 0:629184210581 0.61 0.10 £180.00 +invoice-subscription 0:59df1d2b0f69 0.68 0.06 hostedplatformservices +invoice-subscription 0:44c1ce3394d2 0.68 0.01 £420.00 +invoice-subscription 0:44c1ce3394d2#1 0.68 0.11 £420.00 +invoice-subscription 0:217bada1d20f 0.65 0.06 analyticsprolicences(5seats) +invoice-subscription 0:599cd58953ce 0.65 0.02 £8.40 +invoice-subscription 0:756b8c62fe05 0.65 0.16 £42.00 +invoice-subscription 0:b055bcc305ed 0.72 0.06 prioritysupportplan +invoice-subscription 0:1077d7cede59 0.72 0.09 £275.00 +invoice-subscription 0:1077d7cede59#1 0.72 0.19 £275.00 +invoice-subscription 0:361537ef6a11 0.67 0.06 voiceadd-on(5seats) +invoice-subscription 0:8bf9ac7b27bd 0.67 0.12 £6.00 +invoice-subscription 0:893d7480f763 0.67 0.18 £30.00 invoice-subscription 0:ab5aa97074c4 0.92 0.04 notes -invoice-subscription 0:4440ed73b83f 0.52 0.04 thisinvoicecoverssoftwaresubscri +invoice-subscription 0:4440ed73b83f 0.40 0.04 thisinvoicecoverssoftwaresubscri invoice-subscription 0:fffc319556fa 0.52 0.04 hostedservicesforthecurrentbilli invoice-subscription 0:d6577e95efba 0.69 0.12 subtotal invoice-subscription 0:adde9b2bd3ad 0.69 0.34 £947.00 @@ -3422,7 +3422,7 @@ invoice-subscription 0:b19b1415ef9b 0.80 1.16 40-05-30 invoice-subscription 0:f92a9c925024 0.86 1.23 accountnumber invoice-subscription 0:ef797c8118f0 0.80 1.23 12345678 invoice-subscription 0:52367a6622b1 0.86 1.43 reference -invoice-subscription 0:04f7247e8e99 0.86 0.04 pleaseincludetheinvoicenumberast +invoice-subscription 0:04f7247e8e99 0.74 0.04 pleaseincludetheinvoicenumberast invoice-subscription 0:7c6ab37d83ef 0.89 0.01 thankyouforyourbusiness. invoice-subscription 0:354ffeb2bbc3 0.79 0.01 paymentisdueby10september2026.if invoice-subscription 0:7f7d98088133 0.81 0.01 foranyqueries,pleasecontactbilli diff --git a/qa/src/test/resources/docx-fidelity/word-windows.tsv b/qa/src/test/resources/docx-fidelity/word-windows.tsv index e759091a3..0dae72d37 100644 --- a/qa/src/test/resources/docx-fidelity/word-windows.tsv +++ b/qa/src/test/resources/docx-fidelity/word-windows.tsv @@ -39,7 +39,7 @@ invoice-modern_long 2 2 162 162 0.23 0.31 0 invoice-obsidian 1 1 81 81 0.28 0.76 0 invoice-payments 1 1 104 104 0.09 0.20 0 invoice-platform 1 1 111 111 0.19 0.41 0 -invoice-subscription 1 1 81 81 0.69 0.97 0 +invoice-subscription 1 1 81 81 0.61 0.86 0 invoice-workspace 1 1 90 90 0.14 0.32 0 letter-blue_banner 1 1 10 10 0.39 0.50 0 letter-boxed_sections 1 1 10 10 0.26 0.39 0 diff --git a/render-docx/README.md b/render-docx/README.md index 023629229..10c424dc5 100644 --- a/render-docx/README.md +++ b/render-docx/README.md @@ -118,6 +118,10 @@ What is not written — each one is named in the export report in the export report as `row paint`. Elsewhere a row that paints is written as a panel holding its columns, what of its borders above and below Word draws past its box taken by the space round it and its padding, and named where neither takes it. +- **What a block above leaves over the next** where the space between them does not take it — + a panel's border below, a line hanging below its block, a negative bottom margin, the tenth of + a point Word keeps between two tables — standing the next block that much lower, named in the + export report as `space above`. - **Translucency where Word holds an opaque colour only** — a cell's shading, a border, a rule, a chip's run shading: the colour is flattened against what Word paints under it — the panel or cell the export shaded, or what the page paints there — and a text header's separator against diff --git a/render-docx/src/main/java/com/demcha/compose/document/backend/semantic/docx/DocxSemanticBackend.java b/render-docx/src/main/java/com/demcha/compose/document/backend/semantic/docx/DocxSemanticBackend.java index e6fc21677..30fa89754 100644 --- a/render-docx/src/main/java/com/demcha/compose/document/backend/semantic/docx/DocxSemanticBackend.java +++ b/render-docx/src/main/java/com/demcha/compose/document/backend/semantic/docx/DocxSemanticBackend.java @@ -439,6 +439,15 @@ public final class DocxSemanticBackend implements SemanticBackend { */ private XWPFTableCell borderBelowCell; + /** + * How far the border below the panel ending the cell just written reaches past that panel's + * box, in points, which the cell carries out ({@link #writeInCell}), and that panel's cell. + * The writer of the cell decides what it does there: what the room the cell is given does not + * hold, the panel's padding below takes first ({@link #takeTheCarriedBorder}). + */ + private double carriedBorder; + private XWPFTableCell carriedBorderCell; + /** The page's height in points, or {@code NaN} when the export has no canvas. */ private double canvasHeight = Double.NaN; @@ -5023,16 +5032,19 @@ private void writePanel(XWPFDocument document, DocumentNode node, ContainerPaint } } for (int index = 0; index < pieces.size(); index++) { + boolean onANewPage = false; if (index > 0) { writePageBreak(document); } else if (currentCell == null && startsAPageOfItsOwn(node)) { - // What the block above leaves below itself stays on its page, as above a table - // the layout moves to a new page (writeTableWithItsOwnSpacing). + // What the block above leaves below itself stays on its page, and the space above + // the panel is held on its own, as at a table the layout moves to a new page + // (writeTableWithItsOwnSpacing). leaveThePageAbove(); + onANewPage = true; } List piece = pieces.get(index); writePanelPiece(document, node, paint, () -> writeChildren(document, piece, spacingOf(node)), - index == 0, index == pieces.size() - 1, false); + index == 0, index == pieces.size() - 1, onANewPage); } } @@ -5069,10 +5081,11 @@ private void writePanelPiece(XWPFDocument document, DocumentNode node, Container if (first) { // Word draws a panel's top and bottom borders past its box where the page strokes them // on the box's edge, taking no room (outsideTheRow). The space above takes the reach - // of the top one, after what the block above leaves below itself, which the table - // takes and names with the rest of its tail (newTable). + // of the top one, after what the block above leaves below itself or pulls out of it, + // which the table takes and names with the rest of its tail (newTable). double reach = heldWhole ? 0 : outsideTheRow(borders.top(), padding.top()); - double taken = Math.min(reach, Math.max(0, pendingSpacingAfter - hangingBelow - borderBelow)); + double taken = Math.min(reach, + Math.max(0, pendingSpacingAfter - hangingBelow - borderBelow - pullBelow)); topNotTaken = reach - taken; pendingSpacingAfter -= taken; } @@ -5229,13 +5242,13 @@ private void writePanelPiece(XWPFDocument document, DocumentNode node, Container if (last) { // What the content leaves below itself in Word past where the page ends it — a last // line hanging past it, a card's border below carried out of the cell — makes Word's - // panel that much taller. The room the page leaves under the content in a panel it - // holds taller takes it first; then the padding below, the line hanging into it as on - // the page; what follows takes the rest out of the space between them, as below a row - // (writeRow). A shape's layers are centred in the height it holds, which takes it. - double roomUnder = heldWhole ? Double.POSITIVE_INFINITY : roomUnderItsContent(node, placed, padding); - double hang = Math.max(0, cellOverhang - roomUnder); - double carried = Math.max(0, borderBelow - Math.max(0, roomUnder - cellOverhang)); + // panel that much taller: a container is as tall as its content and padding, and + // leaves no room under the content to take it. Its padding below takes it, the line + // hanging into it as on the page; what follows takes the rest out of the space between + // them, as below a row (writeRow). A card's border is the card's padding's to take + // first. A shape's layers are centred in the outline's height it holds, which takes it. + double hang = heldWhole ? 0 : cellOverhang; + double carried = takeTheCarriedBorder(heldWhole ? 0 : carriedBorder); double fromThePaddingBelow = takeOffTheCellMargin(cell, false, hang + carried); hangingBelow = Math.max(hangingBelow, hang - fromThePaddingBelow); carried = Math.max(0, carried - Math.max(0, fromThePaddingBelow - hang)); @@ -5256,24 +5269,18 @@ private void writePanelPiece(XWPFDocument document, DocumentNode node, Container } /** - * How much room the page leaves under a panel's content, above its padding, in points: what - * the panel's height holds below its lowest child, beyond that child's own margin. 0 where the - * panel's height is not held ({@link #holdThePanelsHeight}) or the layout does not say. + * Takes what it can of a border the cell just written carries out of the padding below of the + * panel ending it ({@link #carriedBorderCell}), the border then drawn that much inside that + * panel's edge. + * + * @return what of the border is left */ - private double roomUnderItsContent(DocumentNode node, com.demcha.compose.document.layout.PlacedNode placed, - DocumentInsets padding) { - if (placed == null || node.children().isEmpty()) { - return 0; - } - double lowest = Double.POSITIVE_INFINITY; - for (DocumentNode child : node.children()) { - com.demcha.compose.document.layout.PlacedNode at = layout.placement(child); - if (at == null || at.startPage() != placed.startPage() || at.endPage() != placed.endPage()) { - return 0; - } - lowest = Math.min(lowest, at.placementY() - Math.max(0, child.margin().bottom())); - } - return Math.max(0, lowest - placed.placementY() - Math.max(0, padding.bottom())); + private double takeTheCarriedBorder(double border) { + XWPFTableCell from = carriedBorderCell; + carriedBorderCell = null; + carriedBorder = 0; + return from == null || !(border > 0) ? Math.max(0, border) + : Math.max(0, border - takeOffTheCellMargin(from, false, border)); } /** @@ -8665,7 +8672,8 @@ private static boolean opensWithATable(DocumentNode node) { * *

Only a table's cell gives its padding, in a row whose margins all even * ({@link #everyMarginEvens}). A panel's cell keeps its: its margin is the padding less half - * its border, and Word sets the content no nearer the border than the border's width.

+ * its border, and Word sets the content its whole border and then that margin inside the row + * ({@link #outsideTheRow}).

* * @return the twips taken, 0 when the paragraph does not open a padded cell */ @@ -8729,6 +8737,8 @@ private void applyVerticalSpacing(XWPFParagraph target, DocumentNode source) { borderNotTakenOver = 0; tailOverNode = null; if (target == pullLeftOn) { + // What of the pull its own top edge cannot give back either stands it lower. + nameTheTailNotTaken(source, 0, 0, 0, pullLeft - Math.min(Math.max(0, before), pullLeft)); before = Math.max(0, before - pullLeft); } pullLeftOn = null; @@ -11701,6 +11711,31 @@ private static CTTcPr cellProperties(XWPFTableCell cell) { : cell.getCTTc().addNewTcPr(); } + /** + * Names the border below a panel ending a table's composed cell, or a column of a layer stack, + * that reaches past the panel's box ({@link #carriedBorder}). + * + *

Word makes the cell's row as tall as the panel and that reach, where the page draws the + * border on the panel's edge. The panel's padding below takes what it can, the border then + * drawn that much inside the panel's edge, as anywhere. The layout does not say how tall such + * a cell's content is against its row, so how much of the rest a taller cell beside it holds + * is not known, and the space under the table does not take it. With no cell beside it + * nothing holds it: the row and what follows stand the rest lower; with cells beside it, up + * to the rest.

+ * + * @param content what the cell holds, which the note is about + * @param alone whether the cell is the only one in its row + */ + private void nameTheBorderEndingACell(DocumentNode content, boolean alone) { + double reach = takeTheCarriedBorder(carriedBorder); + if (reach > TAIL_CLEARANCE) { + report.add(DocxExportReport.Severity.APPROXIMATED, content.nodeKind(), layout.pathOf(content), + "in a table's cell, Word draws the border below the panel ending it " + pointsOf(reach) + + "pt past that panel's box, and the row and what follows stand " + (alone ? "" : "up to ") + + "as much lower" + (alone ? "" : " where no cell beside it holds the border")); + } + } + private void writeCellContent(XWPFTableCell cell, TableGrid.Placement placement, TableNode node) throws Exception { DocumentTableCell source = placement.cell(); @@ -11723,6 +11758,7 @@ private void writeCellContent(XWPFTableCell cell, TableGrid.Placement placement, currentCellWidth = previous; composedCellBoxes = outerBoxes; } + nameTheBorderEndingACell(source.content(), TableGrid.columnCount(node) == 1); return; } List lines = source.lines(); @@ -12173,11 +12209,11 @@ private void writeRow(XWPFDocument document, RowNode node, boolean inItsPanel) t // MerchantInvoice's due-date text stood against its card's top without it. boolean inAPanel = surfaceBehind != null && panelCell != null; com.demcha.compose.document.layout.PlacedNode placedRow = layout.placement(node); + // How far the cell reaching furthest past the row's foot does, its hanging line's share and + // its card's border's (see below). + double rowReach = 0; double rowOverhang = 0; - // A card's border below the last thing in a cell reaches past the row only by what the - // row's room under that cell does not hold, as a hanging line does. double rowBorder = 0; - double borderAbove = borderBelow; // A row's cells are unshaded: inside a panel — its own, where it paints (writePaintedRow), or // a container's — it is a table nested in the panel's cell, and shows the panel's through them. for (int i = 0; i < node.children().size(); i++) { @@ -12191,7 +12227,6 @@ private void writeRow(XWPFDocument document, RowNode node, boolean inItsPanel) t leftMarginInCell = placedColumns ? child : null; cellHang = -hang; cellOverhang = 0; - borderBelow = 0; try { writeRowCellChild(cell, child); } finally { @@ -12199,15 +12234,25 @@ private void writeRow(XWPFDocument document, RowNode node, boolean inItsPanel) t leftMarginInCell = previousHeld; cellHang = 0; } + // A cell's last line hanging past its child and a card's border below that child reach + // one past the other: the row's room under the cell takes the two together, the line + // first. Where the layout does not say, the line is taken to fit and the border to + // reach whole, and is named if nothing takes it. double roomBelow = roomBelowInItsRow(child, placedRow, node); - rowOverhang = Math.max(rowOverhang, cellOverhang - roomBelow); - // Where the layout does not say, the border is the row's whole, and named if nothing takes it. - rowBorder = Math.max(rowBorder, borderBelow - (Double.isInfinite(roomBelow) ? 0 : roomBelow)); - borderBelow = 0; + boolean told = !Double.isInfinite(roomBelow); + double overhang = told ? Math.max(0, cellOverhang - roomBelow) : 0; + // What of the border the room does not hold, the card's padding takes first. + double border = takeTheCarriedBorder( + Math.max(0, carriedBorder - (told ? Math.max(0, roomBelow - cellOverhang) : 0))); + if (overhang + border > rowReach) { + rowReach = overhang + border; + rowOverhang = overhang; + rowBorder = border; + } cellOverhang = 0; applyRowVerticalAlign(cell, node.verticalAlign()); } - borderBelow = Math.max(borderAbove, rowBorder); + borderBelow = rowBorder; borderBelowCell = null; giveTheLastCellItsInk(table, node, placedColumns); // Anywhere, a row whose tallest child is one Word holds nothing of in its cell — a @@ -12226,12 +12271,9 @@ private void writeRow(XWPFDocument document, RowNode node, boolean inItsPanel) t // A cell's last line hanging past the row's foot makes Word's row that much taller, and // takes as much of the gap under it, as text hanging below a band does (writeLinePair): // TimelineMinimal's last contact line, held to its icon, stood 1.8pt below the row, and - // the page under the header with it. - // A card's border below another cell (borderBelow) makes the row taller too: Word's row - // is as tall as the taller of the two, so only what passes the border is added to it. - if (rowOverhang - borderBelow > 0) { - hangingBelow = Math.max(hangingBelow, rowOverhang - borderBelow); - } + // the page under the header with it. A card's border below the last thing in a cell makes + // the row taller too, after the line: Word's row is as tall as the cell reaching furthest. + hangingBelow = Math.max(hangingBelow, rowOverhang); } /** @@ -12501,6 +12543,9 @@ < availableWidth() - EDITOR_COLUMN_SLACK_POINTS - 0.5) { currentCellWidth = previous; resumeSpacing = Double.NaN; } + if (!layers.isEmpty()) { + nameTheBorderEndingACell(layers.get(layers.size() - 1), columns.size() == 1); + } if (cell.getParagraphs().isEmpty()) { cell.addParagraph(); } @@ -13850,10 +13895,14 @@ private XWPFTable newTable(XWPFDocument document, int rows, int columns) { // the space out of the page and everything below the table moved up. owePendingSpacingAfter(carriedSpacingBefore); carriedSpacingBefore = 0; + // A pull out of the block above comes out of that gap first, as the page sums them. // Text hanging below the band above took that much of the gap above this table, and // so did a card's border standing below the card (writePanelPiece): what the gap could - // not give of either, and of the paragraph between two tables, stands the table lower. - double hangNotTaken = Math.max(0, hangingBelow - Math.max(0, pendingSpacingAfter)); + // not give of these, and of the paragraph between two tables, stands the table lower. + double pullNotGiven = Math.max(0, pullBelow - Math.max(0, pendingSpacingAfter)); + pendingSpacingAfter = Math.max(0, pendingSpacingAfter - pullBelow); + pullBelow = 0; + double hangNotTaken = Math.max(0, hangingBelow - pendingSpacingAfter); double borderNotTaken = Math.max(0, borderBelow - Math.max(0, pendingSpacingAfter - hangingBelow)); pendingSpacingAfter = Math.max(0, pendingSpacingAfter - hangingBelow - borderBelow); hangingBelow = 0; @@ -13863,7 +13912,7 @@ private XWPFTable newTable(XWPFDocument document, int rows, int columns) { separatorNotTaken = Math.max(0, SEPARATOR_POINTS - pendingSpacingAfter); separateFromTheTableAbove(document); } - nameTheTailNotTaken(writing, borderNotTaken, hangNotTaken, separatorNotTaken); + nameTheTailNotTaken(writing, borderNotTaken, hangNotTaken, separatorNotTaken, pullNotGiven); // With no paragraph before it in the body — the table opens the document or a section, // or follows a page break — a hairline one carries it: ClassicInvoice opens with a row // under its page padding, and without it stood against the paper's top edge in Word. @@ -14235,6 +14284,8 @@ private void writeInCell(XWPFTableCell cell, CellContent content) throws Excepti double previousHangingOverBy = hangingOverBy; double previousBorderNotTakenOver = borderNotTakenOver; DocumentNode previousTailOverNode = tailOverNode; + XWPFParagraph previousPullLeftOn = pullLeftOn; + double previousPullLeft = pullLeft; double previousInsetLeft = insetLeft; double previousInsetRight = insetRight; double previousTextShift = cellTextShift; @@ -14248,6 +14299,8 @@ private void writeInCell(XWPFTableCell cell, CellContent content) throws Excepti borderBelow = 0; borderBelowCell = null; forgetTheHang(); + pullLeftOn = null; + pullLeft = 0; // A cell's content is measured from the cell's own edge, which its margins already // keep clear of the border; the containers around the table have nothing to add. A row // hanging left out of the cell holding it moves this cell's text only (see cellHang). @@ -14284,16 +14337,20 @@ private void writeInCell(XWPFTableCell cell, CellContent content) throws Excepti carriedSpacingBefore = previousCarried; pendingSpacingAfter = previousOwed; pullBelow = previousPull; - // A card's border below the last thing in a cell stands below the row too, where - // Word makes the row as tall as its tallest cell; the cell beside it starts clear. - // The row's, it is no longer one card's padding to take. - borderBelowCell = previousBorderBelow >= borderBelow ? previousBorderBelowCell : null; - borderBelow = Math.max(previousBorderBelow, borderBelow); + // A card's border below the last thing in a cell reaches past the cell too, where + // Word makes the row as tall as its tallest cell: the writer of the cell says how far + // past its row, which it alone knows. The cell beside it starts clear. + carriedBorder = borderBelow; + carriedBorderCell = borderBelow > 0 ? borderBelowCell : null; + borderBelowCell = previousBorderBelowCell; + borderBelow = previousBorderBelow; hangingBelow = previousHangingBelow; hangingOver = previousHangingOver; hangingOverBy = previousHangingOverBy; borderNotTakenOver = previousBorderNotTakenOver; tailOverNode = previousTailOverNode; + pullLeftOn = previousPullLeftOn; + pullLeft = previousPullLeft; insetLeft = previousInsetLeft; insetRight = previousInsetRight; cellTextShift = previousTextShift; @@ -14411,8 +14468,10 @@ private void writeSpacer(XWPFDocument document, SpacerNode node) throws Exceptio height -= takeTheTailOutOf(height); forgetTheHang(); } - // So does a pull out of the paragraph above that the space above it did not give. + // So does a pull out of the paragraph above that the space above it did not give, and + // what the height cannot give back of it stands what follows lower. if (pullLeftOn == para) { + nameTheTailNotTaken(node, 0, 0, 0, pullLeft - Math.min(height, pullLeft)); height = Math.max(0, height - pullLeft); pullLeftOn = null; pullLeft = 0; @@ -14438,17 +14497,17 @@ private void forgetTheHang() { } /** - * Names a hang a paragraph was to take out of its own top edge and never did — nothing of - * its own was written above it (applyVerticalSpacing, writeSpacer) — before the next block - * takes the hang's place: all of it stands that paragraph lower. + * Names a hang, or a pull, a paragraph was to take out of its own top edge and never did — + * nothing of its own was written above it (applyVerticalSpacing, writeSpacer) — before the + * next block takes its place: all of it stands that paragraph lower. */ private void nameAHangLeftOver() { - if (hangingOver != null) { - nameTheTailNotTaken(tailOverNode, borderNotTakenOver, hangingOverBy, 0); - hangingOver = null; - hangingOverBy = 0; - borderNotTakenOver = 0; - tailOverNode = null; + if (hangingOver != null || pullLeftOn != null) { + nameTheTailNotTaken(tailOverNode, hangingOver != null ? borderNotTakenOver : 0, + hangingOver != null ? hangingOverBy : 0, 0, pullLeftOn != null ? pullLeft : 0); + forgetTheHang(); + pullLeftOn = null; + pullLeft = 0; } } @@ -14462,7 +14521,7 @@ private void nameAHangLeftOver() { private double takeTheTailOutOf(double room) { double hangTaken = Math.min(room, hangingOverBy); double borderTaken = Math.min(room - hangTaken, borderNotTakenOver); - nameTheTailNotTaken(tailOverNode, borderNotTakenOver - borderTaken, hangingOverBy - hangTaken, 0); + nameTheTailNotTaken(tailOverNode, borderNotTakenOver - borderTaken, hangingOverBy - hangTaken, 0, 0); return hangTaken + borderTaken; } @@ -14486,15 +14545,18 @@ private double takeTheTailOutOf(double room) { *
  • the paragraph Word needs between two tables, which the page does not have * ({@link #separateFromTheTableAbove}).
  • * + * So is a pull of the block above — an edge below zero, which the page sets this block over + * that one by — past what the space and the block's own top edge give back: Word sets no block + * over another. * * @param node the block that stands lower, or {@code null} where no block of the writer's is */ - private void nameTheTailNotTaken(DocumentNode node, double border, double hang, double separator) { + private void nameTheTailNotTaken(DocumentNode node, double border, double hang, double separator, double pull) { if (border > 0 && borderBelowCell != null) { border = Math.max(0, border - takeOffTheCellMargin(borderBelowCell, false, border)); borderBelowCell = null; } - double all = Math.max(0, border) + Math.max(0, hang) + Math.max(0, separator); + double all = Math.max(0, border) + Math.max(0, hang) + Math.max(0, separator) + Math.max(0, pull); if (!(all > TAIL_CLEARANCE)) { return; } @@ -14508,9 +14570,17 @@ private void nameTheTailNotTaken(DocumentNode node, double border, double hang, if (separator > 0) { held.add("the paragraph Word keeps between two tables (" + pointsOf(separator) + "pt)"); } + List because = new ArrayList<>(2); + if (!held.isEmpty()) { + because.add("the space the page leaves above it does not hold " + listed(held)); + } + if (pull > 0) { + because.add("the page sets it " + pointsOf(pull) + "pt over the block above it, and Word sets no block " + + "over another"); + } report.add(DocxExportReport.Severity.APPROXIMATED, "space above", node == null ? null : layout.pathOf(node), - "it stands " + pointsOf(all) + "pt lower than the page sets it, and what follows with it: the space the " - + "page leaves above it does not hold " + listed(held)); + "it stands " + pointsOf(all) + "pt lower than the page sets it, and what follows with it: " + + String.join("; ", because)); } private void writePageBreak(XWPFDocument document) { diff --git a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxNodeFieldLedgerTest.java b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxNodeFieldLedgerTest.java index 96a7a463a..58b2e08b4 100644 --- a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxNodeFieldLedgerTest.java +++ b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxNodeFieldLedgerTest.java @@ -97,9 +97,15 @@ private record Entry(Fate fate, String note) { // padding do not take stands the content, or the block below, lower, and is reported. private static final String PANEL_BORDERS = "its translucency, as a panel's, flattened against the colour " + "under it, a border's against the panel's fill where it has one; " - + "what of a border above or below Word draws past the panel's box " - + "that neither the space round it nor its padding takes; any other " - + "is written"; + + "what of a border above Word draws past the panel's box that " + + "neither the space above it, its padding nor the room over its " + + "first line takes, on the panel; below, what neither the space " + + "below it nor its padding takes, on the block below " + + "(space above); any other is written"; + // An edge below zero pulls the next block up; Word sets no block over another. + private static final String PULL = "below zero below it, the pull the space under it and the next block's own " + + "top edge do not give back, on the next block (space above); any other is " + + "written"; private static final String RULE_TRANSLUCENCY = "its translucency, as a rule's, flattened against the colour " + "under it; drawn, its alpha is written; any other is written"; private static final String CELL_TRANSLUCENCY = "the translucency of a cell's fill, flattened against the colour " @@ -113,8 +119,8 @@ private record Entry(Fate fate, String note) { + "text, with a padding below zero or a column hanging into it, and " + "with a margin below zero above or below it or at a side in a cell; " + "its translucency, as a panel's, and what of a border above or below " - + "Word draws past the panel's box that neither the space round it nor " - + "its padding takes; any other is written, as a panel"; + + "Word draws past the panel's box nothing round it takes, as a " + + "panel's; any other is written, as a panel"; private static final Map, Map> NODES = new LinkedHashMap<>(); private static final Map OUTPUT_OPTIONS = fields( @@ -155,7 +161,7 @@ private record Entry(Fate fate, String note) { "margin:REPORTED:in the chart's note; above and below; below a block a band or a column measures from, written", "padding:REPORTED:in the chart's note; above and below; below a block a band or a column measures from, written"); node(ContainerNode.class, "name:INERT", "children:WRITTEN", "spacing:WRITTEN", "padding:WRITTEN", - "margin:WRITTEN", "fillColor:REPORTED:" + PANEL_TRANSLUCENCY, "stroke:REPORTED:" + PANEL_BORDERS, + "margin:REPORTED:" + PULL, "fillColor:REPORTED:" + PANEL_TRANSLUCENCY, "stroke:REPORTED:" + PANEL_BORDERS, "cornerRadius:REPORTED", "borders:REPORTED:" + PANEL_BORDERS, "anchor:REPORTED:as a layer stack's column, which has no bookmark; in the flow it is bookmarked", "bookmarkOptions:REPORTED", "flowWidth:REPORTED:of an unpainted one, a panel in a table cell and a layer stack's column"); @@ -225,7 +231,7 @@ private record Entry(Fate fate, String note) { "bookmarkOptions:REPORTED:a title that is not the text Word lists it by, a pair's whole line for " + "a side of one; a level past Word's ninth that shares it with another; the right side's of a " + "pair whose left holds the level", - "padding:WRITTEN", "margin:WRITTEN", + "padding:REPORTED:" + PULL, "margin:REPORTED:" + PULL, "autoSize:REPORTED:where the layout does not tell the size the page fits the text in the " + "paragraph's style to — no lines read, lines in sizes that do not say which is the " + "paragraph's, or one paragraph added at more than one place — the text written at its " @@ -250,7 +256,7 @@ private record Entry(Fate fate, String note) { node(com.demcha.compose.document.layout.HorizontalBandContentNode.class, "name:INERT", "key:INERT", "slot:WRITTEN", "child:WRITTEN"); node(SectionNode.class, "name:INERT", "children:WRITTEN", "spacing:WRITTEN", "padding:WRITTEN", - "margin:WRITTEN", "fillColor:REPORTED:" + PANEL_TRANSLUCENCY, "stroke:REPORTED:" + PANEL_BORDERS, + "margin:REPORTED:" + PULL, "fillColor:REPORTED:" + PANEL_TRANSLUCENCY, "stroke:REPORTED:" + PANEL_BORDERS, "cornerRadius:REPORTED", "borders:REPORTED:" + PANEL_BORDERS, "keepTogether:WRITTEN", "anchor:REPORTED:as a layer stack's column, which has no bookmark; in the flow it is bookmarked", diff --git a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelHeightTest.java b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelHeightTest.java index 8faf56c67..35cbe4ae2 100644 --- a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelHeightTest.java +++ b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelHeightTest.java @@ -212,7 +212,7 @@ void aPaddedPanelOpeningACellKeepsTheSpaceOverItsFirstLine() throws Exception { } @Test - void aPanelRuledAboveOnlyOpeningACellKeepsTheHeightItHeld() throws Exception { + void aPanelRuledAboveOnlyOpeningACellHoldsItsContentLessTheBorderTakenOverItsHeading() throws Exception { // Its one border is taken over its heading, as an outlined panel's top border is: the // content's height held is that much less, and nothing more comes off for it. XWPFTableCell ruled = panelInARow(1, 0, true); diff --git a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelTailTest.java b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelTailTest.java index ab611af9a..abf05cf60 100644 --- a/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelTailTest.java +++ b/render-docx/src/test/java/com/demcha/compose/document/backend/semantic/docx/DocxPanelTailTest.java @@ -4,6 +4,7 @@ import com.demcha.compose.document.api.DocumentSession; import com.demcha.compose.document.dsl.PageFlowBuilder; import com.demcha.compose.document.dsl.SectionBuilder; +import com.demcha.compose.document.node.DocumentNode; import com.demcha.compose.document.node.InlineImageAlignment; import com.demcha.compose.document.style.DocumentBorders; import com.demcha.compose.document.style.DocumentColor; @@ -101,9 +102,9 @@ void aCardWithNoPaddingNamesItsTopBorderNothingTakes() throws Exception { } @Test - void twoTouchingCardsNameAllThatStandsTheSecondLowerAtOnce() throws Exception { - // The first one's border below, the second one's above, and the paragraph Word keeps - // between two tables: one note, the whole of it. + void twoTouchingCardsNameBothBordersAndTheParagraphBetweenThem() throws Exception { + // The first one's border below and the paragraph Word keeps between two tables stand the + // second lower, named together on it; its own border above stands its content lower. Exported exported = export(page -> page .addSection("First", card -> card.fillColor(SURFACE).borders(DocumentBorders.bottom(RULE)) .addParagraph("One")) @@ -117,43 +118,157 @@ void twoTouchingCardsNameAllThatStandsTheSecondLowerAtOnce() throws Exception { + "past the box of the panel above it (2pt) and the paragraph Word keeps " + "between two tables (0.1pt)"); }); - assertThat(exported.report().bySubject().get("SectionNode")).singleElement() - .satisfies(note -> assertThat(note.detail()).startsWith("its content stands 2pt lower")); + assertThat(exported.report().bySubject().get("SectionNode")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("Second"); + assertThat(note.detail()).isEqualTo("its content stands 2pt lower than the page sets it, and what follows " + + "up to as much: Word sets it below the whole of its top border, and " + + "neither the space above it nor its padding takes what of the border " + + "reaches past the panel's box"); + }); } @Test - void aCardsBorderCarriedOutOfARowsCellIsNoLongerItsPaddingsToTake() throws Exception { - // Below the row, the border is the row's: Word makes the row as tall as its tallest cell, - // which the card's padding does not decide. + void aCardsBorderEndingARowsCellComesOutOfItsPaddingWhereTheRowHoldsNoMore() throws Exception { + // The card is as tall as the row, which leaves no room under it: its padding takes its + // border, and the row is as tall as the page's. Exported exported = export(page -> page.addRow(row -> row .addSection("Card", card -> card.fillColor(SURFACE).borders(DocumentBorders.bottom(RULE)) .padding(DocumentInsets.of(4)).addParagraph("Inside")) .addParagraph("Beside")) .addParagraph(p -> p.name("After").text("After"))); - XWPFTableCell card = exported.document().getTables().get(0).getRow(0).getCell(0).getTables().get(0) - .getRow(0).getCell(0); - assertThat(bottomMargin(card)).as("its padding, less half the border").isEqualTo(3 * 20); + assertThat(bottomMargin(nestedPanel(exported))).as("its padding, less the whole border").isEqualTo(2 * 20); + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + } + + @Test + void aCardsBorderEndingARowsCellItsPaddingCannotHoldIsNamedBelowTheRow() throws Exception { + Exported exported = export(page -> page.addRow(row -> row + .addSection("Card", card -> card.fillColor(SURFACE).borders(DocumentBorders.bottom(RULE)) + .addParagraph("Inside")) + .addParagraph("Beside")) + .addParagraph(p -> p.name("After").text("After"))); + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { assertThat(note.path()).contains("After"); - assertThat(note.detail()).isEqualTo("it stands 1pt lower than the page sets it, and what follows with it: the " + assertThat(note.detail()).isEqualTo("it stands 2pt lower than the page sets it, and what follows with it: the " + "space the page leaves above it does not hold the border Word draws past " - + "the box of the panel above it (1pt)"); + + "the box of the panel above it (2pt)"); + }); + } + + @Test + void aRowsCellReachesPastTheRowByItsHangAndItsCardsBorderTogether() throws Exception { + // The line hanging below the card's text and the card's border below it reach one past + // the other: the row stands taller by both. + Exported exported = export(page -> page.addRow(row -> row + .addSection("Card", card -> { + card.fillColor(SURFACE).borders(DocumentBorders.bottom(RULE)).padding(DocumentInsets.of(1)); + contact(card); + }) + .addParagraph("Beside")) + .addParagraph(p -> p.name("After").text("After"))); + long down = reachBelow(exported, "Iconed"); + + assertThat(down).as("the line reaches below the page's").isPositive(); + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("After"); + assertThat(note.detail()).isEqualTo("it stands " + points(down + 20) + "pt lower than the page sets it, and " + + "what follows with it: the space the page leaves above it does not hold " + + "the border Word draws past the box of the panel above it (1pt) and the " + + "line hanging below the block above it (" + points(down) + "pt)"); }); } @Test - void aCardsBorderCarriedOutOfATablesCellIsNoLongerItsPaddingsToTake() throws Exception { - var card = new com.demcha.compose.document.dsl.SectionBuilder().name("Card").fillColor(SURFACE) - .borders(DocumentBorders.bottom(RULE)).padding(DocumentInsets.of(4)) - .addParagraph("Inside").build(); + void aCardAloneInATablesColumnTakesItsBorderOutOfItsPadding() throws Exception { Exported exported = export(page -> page.addTable(table -> table.columns(DocumentTableColumn.fixed(120)) - .rowCells(DocumentTableCell.node(card))) + .rowCells(DocumentTableCell.node(card(4)))) .addParagraph(p -> p.name("After").text("After"))); - XWPFTableCell inner = exported.document().getTables().get(0).getRow(0).getCell(0).getTables().get(0) - .getRow(0).getCell(0); - assertThat(bottomMargin(inner)).as("its padding, less half the border").isEqualTo(3 * 20); + assertThat(bottomMargin(nestedPanel(exported))).as("its padding, less the whole border").isEqualTo(2 * 20); + assertThat(exported.report().notes()).noneSatisfy(note -> assertThat(note.detail()).contains("border")); + } + + @Test + void aCardAloneInATablesColumnNamesTheBorderItsPaddingCannotHold() throws Exception { + // Nothing beside it holds the border: the row, and what follows, stand that much lower. + Exported exported = export(page -> page.addTable(table -> table.columns(DocumentTableColumn.fixed(120)) + .rowCells(DocumentTableCell.node(card(0)))) + .addParagraph(p -> p.name("After").text("After"))); + + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + assertThat(exported.report().bySubject().get("SectionNode")).singleElement() + .extracting(DocxExportReport.Note::detail).isEqualTo("in a table's cell, Word draws the border below " + + "the panel ending it 2pt past that panel's box, and the row and what follows stand as much lower"); + } + + @Test + void aCardBesideAnotherCellInATableTakesItsBorderOutOfItsPadding() throws Exception { + Exported exported = export(page -> page.addTable(table -> table + .columns(DocumentTableColumn.fixed(120), DocumentTableColumn.fixed(120)) + .rowCells(DocumentTableCell.node(card(4)), DocumentTableCell.node(tall()))) + .addParagraph(p -> p.name("After").text("After"))); + + assertThat(bottomMargin(nestedPanel(exported))).as("its padding, less the whole border").isEqualTo(2 * 20); + assertThat(exported.report().notes()).noneSatisfy(note -> assertThat(note.detail()).contains("border")); + } + + @Test + void aCardBesideATallerCellInATableIsNamedUpToItsBorder() throws Exception { + // The layout does not say how tall a composed cell's content is against its row: the cell + // beside the card may hold what its padding cannot, and the space under the table does not + // take it. + Exported exported = export(page -> page.addTable(table -> table + .columns(DocumentTableColumn.fixed(120), DocumentTableColumn.fixed(120)) + .rowCells(DocumentTableCell.node(card(0)), DocumentTableCell.node(tall()))) + .addParagraph(p -> p.name("After").text("After"))); + + assertThat(before(paragraph(exported, "After"))).as("the space under the table, whole").isZero(); + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + assertThat(exported.report().bySubject().get("SectionNode")).singleElement() + .extracting(DocxExportReport.Note::detail).isEqualTo("in a table's cell, Word draws the border below " + + "the panel ending it 2pt past that panel's box, and the row and what follows stand up to as much " + + "lower where no cell beside it holds the border"); + } + + /** A cell of four lines, taller than a card of one. */ + private static DocumentNode tall() { + return new SectionBuilder().name("Tall").addParagraph("L1").addParagraph("L2").addParagraph("L3") + .addParagraph("L4").build(); + } + + @Test + void aCardEndingAColumnOfLayersBesideAnotherIsNamedUpToItsBorder() throws Exception { + // Side-by-side layers are the cells of one row, which the layout does not measure the + // columns' content against: what of the card's border its padding cannot hold is named, + // and the space under the stack takes nothing for it. + Exported exported = export(page -> page.addLayerStack(stack -> stack.name("Columns") + .layer(column("Sidebar", 0, 240, side -> side.addSection("Card", card -> card.fillColor(SURFACE) + .borders(DocumentBorders.bottom(RULE)).addParagraph("Inside"))), + com.demcha.compose.document.node.LayerAlign.TOP_LEFT) + .layer(column("Main", 120, 0, main -> main.addParagraph("Line").addParagraph("Line") + .addParagraph("Line").addParagraph("Line")), com.demcha.compose.document.node.LayerAlign.TOP_LEFT)) + .addParagraph(p -> p.name("After").text("After"))); + + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + assertThat(exported.report().notes()).anySatisfy(note -> assertThat(note.detail()).isEqualTo("in a table's cell, " + + "Word draws the border below the panel ending it 2pt past that panel's box, and the row and what " + + "follows stand up to as much lower where no cell beside it holds the border")); + } + + /** A layer of a stack, held in from the stack's sides as DocxLayerColumnsTest's columns are. */ + private static DocumentNode column(String name, double insetLeft, double insetRight, Consumer content) { + SectionBuilder layer = new SectionBuilder(); + layer.name(name).spacing(0).padding(new DocumentInsets(0, insetRight, 0, insetLeft)); + layer.addSection(name + "Content", section -> content.accept(section.spacing(0))); + return layer.build(); + } + + /** A card ruled below by {@link #RULE}, padded {@code padding} on every side. */ + private static DocumentNode card(double padding) { + return new SectionBuilder().name("Card").fillColor(SURFACE).borders(DocumentBorders.bottom(RULE)) + .padding(DocumentInsets.of(padding)).addParagraph("Inside").build(); } @Test @@ -168,23 +283,13 @@ void aPaddedCardsTopBorderComesOutOfItsPaddingWhereNoSpaceAboveTakesIt() throws @Test void anOutlinedCardHoldsTheHeightOfItsContent() throws Exception { // The editors read a panel's written height as its content's, its margins and both its - // borders round it: held less its margins and one border, an outlined card padded 4pt - // stood a point taller than the page's. - double height; - byte[] docx; - AtomicReference report = new AtomicReference<>(); - try (DocumentSession session = GraphCompose.document().pageSize(400, 400).margin(DocumentInsets.of(20)).create()) { - session.pageFlow(page -> page.addSection("Card", card -> card.fillColor(SURFACE).stroke(RULE) - .padding(DocumentInsets.of(4)).addParagraph("Inside")).addParagraph("After")); - height = session.layoutGraph().nodes().stream().filter(node -> "Card".equals(node.semanticName())) - .findFirst().orElseThrow().placementHeight(); - docx = session.export(new DocxSemanticBackend(report::set)); - } - try (XWPFDocument document = new XWPFDocument(new ByteArrayInputStream(docx))) { - var row = document.getTables().get(0).getRow(0); - assertThat(row.getHeight()).as("the page's height, less its padding").isEqualTo(Math.round((height - 8) * 20)); - assertThat(report.get().bySubject()).doesNotContainKey("space above").doesNotContainKey("SectionNode"); - } + // borders round it: the page's height, less its padding. + Exported exported = export(page -> page.addSection("Card", card -> card.fillColor(SURFACE).stroke(RULE) + .padding(DocumentInsets.of(4)).addParagraph("Inside")).addParagraph("After")); + + assertThat(panel(exported).getTableRow().getHeight()).as("the page's height, less its padding") + .isEqualTo(Math.round((exported.heights().get("Card") - 8) * 20)); + assertThat(exported.report().bySubject()).doesNotContainKey("space above").doesNotContainKey("SectionNode"); } @Test @@ -334,17 +439,101 @@ void aCardsBorderBesideATallerCellReachesNoFurtherThanTheRow() throws Exception } @Test - void aMarginBelowZeroUnderAPanelIsNoBorder() throws Exception { - // It pulls what follows up, as a paragraph's does: the panel keeps its padding, and no - // border is named. - Exported exported = export(page -> page.addSection("Card", card -> card.fillColor(SURFACE) + void aMarginBelowZeroUnderAPanelPullsWhatFollowsUp() throws Exception { + // As a paragraph's does: out of the space under the panel, which keeps its padding. + Exported exported = export(page -> page.spacing(10).addSection("Card", card -> card.fillColor(SURFACE) .padding(DocumentInsets.of(8)).margin(new DocumentInsets(0, 0, -4, 0)).addParagraph("Inside")) .addParagraph(p -> p.name("After").text("After"))); assertThat(bottomMargin(panel(exported))).isEqualTo(8 * 20); + assertThat(before(paragraph(exported, "After"))).as("the gap, less the pull").isEqualTo(6 * 20); + assertThat(exported.report().bySubject()).doesNotContainKey("space above"); + } + + @Test + void aPullNoSpaceGivesIsNamed() throws Exception { + // The page sets the paragraph over the panel; Word sets no block over another. + Exported exported = export(page -> page.addSection("Card", card -> card.fillColor(SURFACE) + .padding(DocumentInsets.of(8)).margin(new DocumentInsets(0, 0, -4, 0)).addParagraph("Inside")) + .addParagraph(p -> p.name("After").text("After"))); + + assertThat(bottomMargin(panel(exported))).as("the panel keeps its padding").isEqualTo(8 * 20); + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("After"); + assertThat(note.detail()).isEqualTo("it stands 4pt lower than the page sets it, and what follows with it: the " + + "page sets it 4pt over the block above it, and Word sets no block over " + + "another"); + }); + } + + @Test + void aPullATableBelowCannotGiveIsNamedWithItsTail() throws Exception { + Exported exported = export(page -> page.addSection("Card", card -> card.fillColor(SURFACE) + .padding(DocumentInsets.of(8)).margin(new DocumentInsets(0, 0, -4, 0)).addParagraph("Inside")) + .addTable(this::first)); + + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("First"); + assertThat(note.detail()).isEqualTo("it stands 4.1pt lower than the page sets it, and what follows with it: " + + "the space the page leaves above it does not hold the paragraph Word " + + "keeps between two tables (0.1pt); the page sets it 4pt over the block " + + "above it, and Word sets no block over another"); + }); + } + + @Test + void aPullASpacerCannotGiveIsNamedOnTheSpacer() throws Exception { + Exported exported = export(page -> page.addParagraph(p -> p.text("Pulling").margin(new DocumentInsets(0, 0, -6, 0))) + .addSpacer(spacer -> spacer.name("Gap").size(0, 2)) + .addParagraph("After")); + + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("Gap"); + assertThat(note.detail()).isEqualTo("it stands 4.1pt lower than the page sets it, and what follows with it: " + + "the page sets it 4.1pt over the block above it, and Word sets no block " + + "over another"); + }); + } + + @Test + void aPullLeftOverABlockWithNoTopEdgeOfItsOwnIsNamed() throws Exception { + // A list item takes nothing out of a top edge of its own: the pull is named all the same. + Exported exported = export(page -> page.addParagraph(p -> p.text("Pulling").margin(new DocumentInsets(0, 0, -4, 0))) + .addList(list -> list.addItem("Only"))); + + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("ListNode"); + assertThat(note.detail()).isEqualTo("it stands 4pt lower than the page sets it, and what follows with it: the " + + "page sets it 4pt over the block above it, and Word sets no block over " + + "another"); + }); + } + + @Test + void aPaddedCardEndingAPanelTakesItsBorderOutOfItsOwnPaddingFirst() throws Exception { + Exported exported = export(page -> page.addSection("Outer", outer -> outer.fillColor(SURFACE) + .padding(DocumentInsets.of(6)).addParagraph("Lead") + .addSection("Inner", inner -> inner.fillColor(DocumentColor.WHITE) + .borders(DocumentBorders.bottom(RULE)).padding(DocumentInsets.of(4)).addParagraph("Inside"))) + .addParagraph(p -> p.name("After").text("After"))); + + assertThat(bottomMargin(nestedPanel(exported))).as("the inner card's padding, less the whole border") + .isEqualTo(2 * 20); + assertThat(bottomMargin(panel(exported))).as("the outer panel's padding, whole").isEqualTo(6 * 20); assertThat(exported.report().bySubject()).doesNotContainKey("space above"); } + @Test + void theSpaceAPullTakesIsNoRoomForACardsTopBorder() throws Exception { + // The card's 6pt top margin is the pull's, and its padding holds its top border instead. + Exported exported = export(page -> page.addParagraph(p -> p.text("Pulling").margin(new DocumentInsets(0, 0, -6, 0))) + .addSection("Card", card -> card.fillColor(SURFACE).borders(DocumentBorders.top(RULE)) + .margin(new DocumentInsets(6, 0, 0, 0)).padding(DocumentInsets.of(4)).addParagraph("Inside"))); + + assertThat(topMargin(panel(exported))).as("its padding, less the whole border").isEqualTo(2 * 20); + assertThat(exported.report().bySubject()).doesNotContainKey("space above").doesNotContainKey("SectionNode"); + } + @Test void aContainersEdgeAboveATableTakesTheTailOfTheBlockAbove() throws Exception { // The section's top padding is space above its table, as above a paragraph. @@ -363,8 +552,12 @@ void aTailLeftOverTheLastBlockIsNamed() throws Exception { .borders(DocumentBorders.bottom(RULE)).addParagraph("Inside")) .addList(list -> list.addItem("Only"))); - assertThat(exported.report().bySubject().get("space above")).singleElement() - .satisfies(note -> assertThat(note.detail()).startsWith("it stands 2pt lower")); + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { + assertThat(note.path()).contains("ListNode"); + assertThat(note.detail()).isEqualTo("it stands 2pt lower than the page sets it, and what follows with it: the " + + "space the page leaves above it does not hold the border Word draws past " + + "the box of the panel above it (2pt)"); + }); } @Test @@ -382,7 +575,28 @@ void aPanelTheLayoutMovesToANewPageLeavesTheTailAbove() throws Exception { assertThat(exported.report().bySubject()).doesNotContainKey("SectionNode"); // The paragraph Word keeps between the two tables goes with the second, and is named. assertThat(exported.report().bySubject().get("space above")).singleElement() - .satisfies(note -> assertThat(note.detail()).doesNotContain("border")); + .extracting(DocxExportReport.Note::detail).isEqualTo("it stands 0.1pt lower than the page sets it, and " + + "what follows with it: the space the page leaves above it does not hold the paragraph Word " + + "keeps between two tables (0.1pt)"); + } + + @Test + void aPanelTheLayoutMovesToANewPageKeepsTheSpaceAboveItThere() throws Exception { + // Word drops a paragraph's space above at the top of a page, as the page keeps it: the + // panel's 12pt are a line of their own above it, kept with it. + Exported exported = export(page -> page.addParagraph("Before").addSpacer(spacer -> spacer.size(0, 470)) + .addSection("Second", card -> card.keepTogether().fillColor(SURFACE) + .margin(new DocumentInsets(12, 0, 0, 0)).padding(DocumentInsets.of(4)).addParagraph("Two") + .addParagraph("Two").addParagraph("Two").addParagraph("Two").addParagraph("Two") + .addParagraph("Two"))); + List body = exported.document().getBodyElements(); + int panel = body.indexOf(exported.document().getTables().get(0)); + XWPFParagraph line = (XWPFParagraph) body.get(panel - 1); + CTSpacing spacing = line.getCTP().getPPr().getSpacing(); + + assertThat(exported.pages().get("Second")).as("the layout moves it to the next page").isEqualTo(1); + assertThat(DocxTwips.of(spacing.getLine())).as("its 12pt").isEqualTo(12 * 20); + assertThat(line.getCTP().getPPr().isSetKeepNext()).isTrue(); } @Test @@ -394,6 +608,8 @@ void theSpaceAboveACardTakesTheHangOfTheBlockAboveBeforeItsBorder() throws Excep Exported exported = hungOverACard(gap); assertThat(reachBelow(exported, "Iconed")).as("the same line").isEqualTo(down); + assertThat(topMargin(panel(exported))).as("its padding less half the border, less the half point the space left") + .isEqualTo((4 - 1) * 20 - 10); assertThat(exported.report().bySubject()).doesNotContainKey("space above").doesNotContainKey("SectionNode"); } @@ -411,10 +627,14 @@ void aHangATableBelowDoesNotTakeIsNamedOnTheTable() throws Exception { contact(card); }).addTable(this::first)); + long down = reachBelow(exported, "Iconed"); + assertThat(exported.report().bySubject().get("space above")).singleElement().satisfies(note -> { assertThat(note.path()).contains("First"); - assertThat(note.detail()).contains("the line hanging below the block above it (") - .contains("the paragraph Word keeps between two tables (0.1pt)"); + assertThat(note.detail()).isEqualTo("it stands " + points(down + 2) + "pt lower than the page sets it, and " + + "what follows with it: the space the page leaves above it does not hold " + + "the line hanging below the block above it (" + points(down) + "pt) and " + + "the paragraph Word keeps between two tables (0.1pt)"); }); } @@ -485,19 +705,34 @@ private static String points(long twips) { * the paragraph's top (the space above it written that much shorter). */ private static long reachBelow(Exported exported, String name) { - // The icon's line, in the body or in the first panel's cell. + // The icon's line — "GitHub" and its icon, in contact() — wherever the tables put it. List paragraphs = new java.util.ArrayList<>(exported.document().getParagraphs()); - exported.document().getTables().forEach(table -> paragraphs.addAll(table.getRow(0).getCell(0).getParagraphs())); + exported.document().getTables().forEach(table -> collect(table, paragraphs)); XWPFParagraph iconed = paragraphs.stream().filter(p -> p.getText().startsWith("GitHub")).findFirst().orElseThrow(); CTSpacing spacing = iconed.getCTP().getPPr().getSpacing(); + assertThat(spacing.getLineRule()).as("held to its icon") + .isEqualTo(org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule.EXACT); long up = 3 * 20 - (spacing.isSetBefore() ? DocxTwips.of(spacing.getBefore()) : 0); return DocxTwips.of(spacing.getLine()) - up - Math.round(exported.heights().get(name) * 20); } + private static void collect(org.apache.poi.xwpf.usermodel.XWPFTable table, List paragraphs) { + table.getRows().forEach(row -> row.getTableCells().forEach(cell -> { + paragraphs.addAll(cell.getParagraphs()); + cell.getTables().forEach(nested -> collect(nested, paragraphs)); + })); + } + + /** The cell of the first table in the body: the panel, where the document opens with one. */ private static XWPFTableCell panel(Exported exported) { return exported.document().getTables().get(0).getRow(0).getCell(0); } + /** The panel nested in the first cell of the first table in the body. */ + private static XWPFTableCell nestedPanel(Exported exported) { + return panel(exported).getTables().get(0).getRow(0).getCell(0); + } + private static long topMargin(XWPFTableCell cell) { return DocxTwips.of(cell.getCTTc().getTcPr().getTcMar().getTop().getW()); } From 00164f8ea73c67d459a1619a00d17dffbf4e26dc Mon Sep 17 00:00:00 2001 From: DemchaAV Date: Thu, 8 Oct 2026 14:02:37 +0100 Subject: [PATCH 3/3] test(qa): rewrite the Linux LibreOffice fidelity baseline for the panel border reach Measured by CI's LibreOffice on Linux on this branch: 24 of the 62 documents change, 11 standing nearer the page in median and 9 further, the same documents and directions as LibreOffice on Windows. --- .../docx-fidelity/libreoffice-linux-lines.tsv | 1751 +++++++++-------- .../docx-fidelity/libreoffice-linux.tsv | 48 +- 2 files changed, 900 insertions(+), 899 deletions(-) diff --git a/qa/src/test/resources/docx-fidelity/libreoffice-linux-lines.tsv b/qa/src/test/resources/docx-fidelity/libreoffice-linux-lines.tsv index 0854e2111..a970fd4ab 100644 --- a/qa/src/test/resources/docx-fidelity/libreoffice-linux-lines.tsv +++ b/qa/src/test/resources/docx-fidelity/libreoffice-linux-lines.tsv @@ -52,46 +52,46 @@ cv-blue_banner 0:88b226d51fe1 0.36 0.10 pngdiffing,side-by-sidelayout,ba cv-blue_banner 0:339245d63103 0.42 0.10 layoutlint(java21,javaparser,spo cv-blue_banner 0:8c87b84946f3 0.72 0.10 beforetheyshiptoproduction. cv-boxed_sections 0:8f1010120ed6 0.46 2.20 jordanrivera -cv-boxed_sections 0:8d7a2cca3060 -0.12 0.12 +442055551000|jordan.rivera@exam -cv-boxed_sections 0:b944906ed84c -0.42 6.44 professionalsummary -cv-boxed_sections 0:80cc87fdc4c4 -0.75 0.10 platformengineerwith10+yearsbuil -cv-boxed_sections 0:bddc0bd093ce -0.75 0.10 systems.specialisedinhigh-throug -cv-boxed_sections 0:95a43d7b3df0 -0.74 0.10 snapshot-testedlibrariesthatscal -cv-boxed_sections 0:5f94c50dc5bf -0.43 6.32 technicalskills -cv-boxed_sections 0:eea537278f83 -0.46 0.10 •languages:java21,kotlin,groovy, -cv-boxed_sections 0:9c2cd7231a53 -0.45 0.10 •document&print:pdfbox,apachepoi -cv-boxed_sections 0:7bf8639ec5d3 -0.45 0.10 •layoutengines:customdsldesign,s -cv-boxed_sections 0:8e66776d28d7 -0.44 0.10 •build&infrastructure:maven,grad -cv-boxed_sections 0:1ed4fc7d7768 -0.44 0.10 •testing:junit5,assertj,pdfbox-b -cv-boxed_sections 0:26671c309eb9 -0.43 0.10 •distribution:mavencentral,sonat -cv-boxed_sections 0:68bf0109c6f8 -0.42 6.18 education -cv-boxed_sections 0:0ad1957d6bab -0.42 0.10 msccomputerscience -cv-boxed_sections 0:3fa772117260 -0.46 -0.76 2019-2021 -cv-boxed_sections 0:47ce0218bbea -0.43 0.10 universityofmanchester -cv-boxed_sections 0:2ffe115b06e5 -0.42 0.10 distinction.thesis:composablelay -cv-boxed_sections 0:b6749d0b616b -0.39 0.10 bscsoftwareengineering -cv-boxed_sections 0:30f9262640a0 -0.42 -0.76 2015-2019 -cv-boxed_sections 0:89ad9656f393 -0.40 0.10 imperialcollegelondon -cv-boxed_sections 0:baa173b4a82e -0.38 0.10 first-classhonours.specialisatio -cv-boxed_sections 0:6d3d5673c39f -0.35 0.10 oraclejavacertification -cv-boxed_sections 0:d40b22f00acb -0.39 -0.76 2023-2024 -cv-boxed_sections 0:2669e1f6d55c -0.36 0.10 professionaltrack -cv-boxed_sections 0:3857373829c1 -0.35 0.10 java17platformdeep-dive:records, -cv-boxed_sections 0:2577c0f557b2 -0.33 6.18 projects -cv-boxed_sections 0:b2b029995203 -0.36 0.10 •graphcompose(java21,pdfbox,mave -cv-boxed_sections 0:67593a76ef70 -0.66 0.11 declarativejavapdflayoutengine.s -cv-boxed_sections 0:b9292cbd1454 -0.65 0.11 pipelinesforhiringtoolsandbillin -cv-boxed_sections 0:1b50bb81df5a -0.35 0.10 •templatestudio(kotlin,composede -cv-boxed_sections 0:836e76daecbf -0.34 0.11 internaltoolforevaluatingcv,prop -cv-boxed_sections 0:25cdca2beb8b -0.34 0.10 •layoutlint(java21,javaparser,sp -cv-boxed_sections 0:7488006d7864 -0.63 0.11 staticanalyserthatflagsfragileau -cv-boxed_sections 0:c4d0c415b4f8 -0.63 0.11 production. -cv-boxed_sections 0:fb1927f88597 -0.32 0.10 •chromeforge(java,graphcompose,p -cv-boxed_sections 0:e7e62230eb1f -0.32 0.11 editorial-magazinedocumenttoolki -cv-boxed_sections 0:c2f296ef30a3 -0.30 6.46 professionalexperience -cv-boxed_sections 0:a76f47480818 -0.31 0.10 seniorplatformengineer -cv-boxed_sections 0:060300b18051 -0.34 0.01 2024-present -cv-boxed_sections 0:f890faef907f -0.32 0.10 northwindsystems +cv-boxed_sections 0:8d7a2cca3060 0.23 0.12 +442055551000|jordan.rivera@exam +cv-boxed_sections 0:b944906ed84c 0.28 6.44 professionalsummary +cv-boxed_sections 0:80cc87fdc4c4 -0.05 0.10 platformengineerwith10+yearsbuil +cv-boxed_sections 0:bddc0bd093ce -0.05 0.10 systems.specialisedinhigh-throug +cv-boxed_sections 0:95a43d7b3df0 -0.04 0.10 snapshot-testedlibrariesthatscal +cv-boxed_sections 0:5f94c50dc5bf 0.27 6.32 technicalskills +cv-boxed_sections 0:eea537278f83 0.24 0.10 •languages:java21,kotlin,groovy, +cv-boxed_sections 0:9c2cd7231a53 0.25 0.10 •document&print:pdfbox,apachepoi +cv-boxed_sections 0:7bf8639ec5d3 0.25 0.10 •layoutengines:customdsldesign,s +cv-boxed_sections 0:8e66776d28d7 0.26 0.10 •build&infrastructure:maven,grad +cv-boxed_sections 0:1ed4fc7d7768 0.26 0.10 •testing:junit5,assertj,pdfbox-b +cv-boxed_sections 0:26671c309eb9 0.27 0.10 •distribution:mavencentral,sonat +cv-boxed_sections 0:68bf0109c6f8 0.28 6.18 education +cv-boxed_sections 0:0ad1957d6bab 0.28 0.10 msccomputerscience +cv-boxed_sections 0:3fa772117260 0.24 -0.76 2019-2021 +cv-boxed_sections 0:47ce0218bbea 0.27 0.10 universityofmanchester +cv-boxed_sections 0:2ffe115b06e5 0.28 0.10 distinction.thesis:composablelay +cv-boxed_sections 0:b6749d0b616b 0.31 0.10 bscsoftwareengineering +cv-boxed_sections 0:30f9262640a0 0.28 -0.76 2015-2019 +cv-boxed_sections 0:89ad9656f393 0.30 0.10 imperialcollegelondon +cv-boxed_sections 0:baa173b4a82e 0.32 0.10 first-classhonours.specialisatio +cv-boxed_sections 0:6d3d5673c39f 0.35 0.10 oraclejavacertification +cv-boxed_sections 0:d40b22f00acb 0.31 -0.76 2023-2024 +cv-boxed_sections 0:2669e1f6d55c 0.34 0.10 professionaltrack +cv-boxed_sections 0:3857373829c1 0.35 0.10 java17platformdeep-dive:records, +cv-boxed_sections 0:2577c0f557b2 0.37 6.18 projects +cv-boxed_sections 0:b2b029995203 0.34 0.10 •graphcompose(java21,pdfbox,mave +cv-boxed_sections 0:67593a76ef70 0.04 0.11 declarativejavapdflayoutengine.s +cv-boxed_sections 0:b9292cbd1454 0.05 0.11 pipelinesforhiringtoolsandbillin +cv-boxed_sections 0:1b50bb81df5a 0.35 0.10 •templatestudio(kotlin,composede +cv-boxed_sections 0:836e76daecbf 0.36 0.11 internaltoolforevaluatingcv,prop +cv-boxed_sections 0:25cdca2beb8b 0.36 0.10 •layoutlint(java21,javaparser,sp +cv-boxed_sections 0:7488006d7864 0.07 0.11 staticanalyserthatflagsfragileau +cv-boxed_sections 0:c4d0c415b4f8 0.07 0.11 production. +cv-boxed_sections 0:fb1927f88597 0.38 0.10 •chromeforge(java,graphcompose,p +cv-boxed_sections 0:e7e62230eb1f 0.38 0.11 editorial-magazinedocumenttoolki +cv-boxed_sections 0:c2f296ef30a3 0.40 6.46 professionalexperience +cv-boxed_sections 0:a76f47480818 0.39 0.10 seniorplatformengineer +cv-boxed_sections 0:060300b18051 0.36 0.01 2024-present +cv-boxed_sections 0:f890faef907f 0.38 0.10 northwindsystems cv-boxed_sections 1:49faf14f1f56 -0.13 0.10 ledthereusabledocument-generatio cv-boxed_sections 1:6bd3f168e89e -0.13 0.10 maintenancetimeby70%byretiringpe cv-boxed_sections 1:daf65306b3b6 0.20 0.10 softwareengineer @@ -174,123 +174,123 @@ cv-charcoal_gold 0:92966f349443 -0.01 0.20 london,unitedkingdom cv-charcoal_gold 0:42535367bd3c -0.01 0.21 anastasiasmith.com cv-charcoal_gold 0:d5d2c85de2b9 -0.01 0.21 linkedin.com/in/anastasiasmith cv-charcoal_gold 0:32c1cf49a2fe -0.23 -0.70 skills -cv-charcoal_gold 0:340455fbac25 -0.11 0.10 projectmanagement -cv-charcoal_gold 0:03cd52ebdc67 -0.11 0.10 budgeting&forecasting -cv-charcoal_gold 0:115925c1b96b -0.11 0.10 stakeholdercommunication -cv-charcoal_gold 0:4e321f38b222 -0.11 0.10 riskmanagement -cv-charcoal_gold 0:2f594f65f16c -0.11 0.10 dataanalysis -cv-charcoal_gold 0:b08c44dac044 -0.11 0.10 processimprovement -cv-charcoal_gold 0:c7b5692b2d27 -0.11 0.10 microsoftexcel -cv-charcoal_gold 0:2e2c6b2f5ad9 -0.11 0.10 powerbi -cv-charcoal_gold 0:f73b1d7d3bc6 -0.11 0.10 jira/confluence -cv-charcoal_gold 0:b011cfad056f -0.11 0.10 agilemethodologies -cv-charcoal_gold 0:6cb574fa10b6 -0.13 -0.70 languages -cv-charcoal_gold 0:b6234d2ea0d6 -0.04 0.10 english -cv-charcoal_gold 0:bef32d2c315a -0.04 0.08 native -cv-charcoal_gold 0:bef32d2c315a#1 -0.04 0.08 native -cv-charcoal_gold 0:aa304b5d1d72 -0.04 0.10 russian -cv-charcoal_gold 0:21bb36ad0638 -0.04 0.10 french -cv-charcoal_gold 0:23ed645595d6 -0.04 0.08 b2–upperintermediate -cv-charcoal_gold 0:28561c6b68fc -0.04 0.10 german -cv-charcoal_gold 0:3cb3c2736bad -0.04 0.08 a2–basic -cv-charcoal_gold 0:68bf0109c6f8 -0.03 -0.70 education -cv-charcoal_gold 0:48f12eb2ea0d -0.01 0.61 mscprojectmanagement -cv-charcoal_gold 0:ede0c8c47a1f -0.01 0.10 universitycollegelondon -cv-charcoal_gold 0:fc3f0389b9de -0.01 0.10 2018–2019 -cv-charcoal_gold 0:66cb4ff79ee1 -0.02 0.61 bscbusinessadministration -cv-charcoal_gold 0:8826393fc0f0 -0.02 0.10 king'scollegelondon -cv-charcoal_gold 0:c7d18ae8c50d -0.02 0.10 2014–2017 +cv-charcoal_gold 0:340455fbac25 -0.21 0.10 projectmanagement +cv-charcoal_gold 0:03cd52ebdc67 -0.21 0.10 budgeting&forecasting +cv-charcoal_gold 0:115925c1b96b -0.21 0.10 stakeholdercommunication +cv-charcoal_gold 0:4e321f38b222 -0.21 0.10 riskmanagement +cv-charcoal_gold 0:2f594f65f16c -0.21 0.10 dataanalysis +cv-charcoal_gold 0:b08c44dac044 -0.21 0.10 processimprovement +cv-charcoal_gold 0:c7b5692b2d27 -0.21 0.10 microsoftexcel +cv-charcoal_gold 0:2e2c6b2f5ad9 -0.21 0.10 powerbi +cv-charcoal_gold 0:f73b1d7d3bc6 -0.21 0.10 jira/confluence +cv-charcoal_gold 0:b011cfad056f -0.21 0.10 agilemethodologies +cv-charcoal_gold 0:6cb574fa10b6 -0.23 -0.70 languages +cv-charcoal_gold 0:b6234d2ea0d6 -0.24 0.10 english +cv-charcoal_gold 0:bef32d2c315a -0.24 0.08 native +cv-charcoal_gold 0:bef32d2c315a#1 -0.24 0.08 native +cv-charcoal_gold 0:aa304b5d1d72 -0.24 0.10 russian +cv-charcoal_gold 0:21bb36ad0638 -0.24 0.10 french +cv-charcoal_gold 0:23ed645595d6 -0.24 0.08 b2–upperintermediate +cv-charcoal_gold 0:28561c6b68fc -0.24 0.10 german +cv-charcoal_gold 0:3cb3c2736bad -0.24 0.08 a2–basic +cv-charcoal_gold 0:68bf0109c6f8 -0.23 -0.70 education +cv-charcoal_gold 0:48f12eb2ea0d -0.21 0.61 mscprojectmanagement +cv-charcoal_gold 0:ede0c8c47a1f -0.21 0.10 universitycollegelondon +cv-charcoal_gold 0:fc3f0389b9de -0.21 0.10 2018–2019 +cv-charcoal_gold 0:66cb4ff79ee1 -0.22 0.61 bscbusinessadministration +cv-charcoal_gold 0:8826393fc0f0 -0.22 0.10 king'scollegelondon +cv-charcoal_gold 0:c7d18ae8c50d -0.22 0.10 2014–2017 cv-charcoal_gold 0:3acba0d7b5dc -0.34 0.09 projectmanager -cv-charcoal_gold 0:3acba0d7b5dc#1 -0.09 0.06 projectmanager +cv-charcoal_gold 0:3acba0d7b5dc#1 -0.19 0.06 projectmanager cv-charcoal_gold 0:f54e0195601a 0.06 0.09 results-drivenprojectmanagerwith cv-charcoal_gold 0:7a0497cef9c6 0.06 0.09 teamsanddeliveringcomplexproject cv-charcoal_gold 0:c38f1902ece8 0.29 0.09 skilledinagileandwaterfallmethod cv-charcoal_gold 0:ca94787c6c7a -0.41 0.09 management.passionateaboutdrivin cv-charcoal_gold 0:53e5e7c5a884 -0.31 -0.71 experience -cv-charcoal_gold 0:086c0e036e67 -0.15 0.09 2021–present -cv-charcoal_gold 0:eddc2d311872 -0.21 0.06 seniorprojectmanager -cv-charcoal_gold 0:243953e20dc4 -0.11 0.06 digitalsolutionsltd·london,uk -cv-charcoal_gold 0:7fde5861c84b -0.04 0.06 •managecross-functionalteamsofup -cv-charcoal_gold 0:80c76af1fe2a -0.02 0.06 •implementagilepracticesthatimpr -cv-charcoal_gold 0:b6bb33b79f44 0.00 0.06 •buildstrongclientrelationshipsa -cv-charcoal_gold 0:6c39082d9294 -0.03 0.09 2019–2021 -cv-charcoal_gold 0:46df57ef8321 0.01 0.06 innovatechsystems·london,uk -cv-charcoal_gold 0:271b01626043 0.04 0.06 •delivered12+projectsacrossitand -cv-charcoal_gold 0:77dd7c2ad6ae 0.06 0.06 •monitoredbudgets,timelines,andr -cv-charcoal_gold 0:bf8278cd4edc 0.08 0.06 •identifiedrisksandimplementedmi -cv-charcoal_gold 0:2773f92777d7 0.10 0.06 •achieved98%on-timeprojectdelive -cv-charcoal_gold 0:ad564a6ee91d 0.07 0.09 2017–2019 -cv-charcoal_gold 0:e085ad3a0d32 0.01 0.06 projectcoordinator -cv-charcoal_gold 0:6ac382583801 0.11 0.06 globalbusinessservices·london,uk -cv-charcoal_gold 0:77aec5bb6b7f 0.14 0.06 •supportedprojectmanagersinplann -cv-charcoal_gold 0:38dafe4a1765 0.16 0.06 •preparedreports,dashboards,andd -cv-charcoal_gold 0:5c95a9041b72 0.18 0.06 •coordinatedmeetingsandtrackedac -cv-charcoal_gold 0:f0d87e2131e2 0.20 0.06 •improvedinternalprocessesandpro -cv-charcoal_gold 0:e831beb04c00 0.11 0.14 certifications -cv-charcoal_gold 0:93a7ba535da0 0.27 0.10 pmp®certification -cv-charcoal_gold 0:0f9f6d10bfa3 0.31 0.10 projectmanagementinstitute -cv-charcoal_gold 0:73a2af8864fc 0.33 0.10 2020 -cv-charcoal_gold 0:73a2af8864fc#1 0.39 0.00 2020 -cv-charcoal_gold 0:043092900ed5 0.30 0.10 prince2®foundation -cv-charcoal_gold 0:544a764703d6 0.34 0.10 axelos -cv-charcoal_gold 0:023e33504ab9 0.36 0.10 2019 -cv-charcoal_gold 0:023e33504ab9#1 0.39 0.10 2019 -cv-charcoal_gold 0:83cd2e790f6a 0.33 0.10 agilepm®foundation -cv-charcoal_gold 0:0005e5872534 0.37 0.10 apmginternational -cv-charcoal_gold 0:6ee18b42fbf1 0.11 0.09 achievements -cv-charcoal_gold 0:3f06e4a3eb33 0.27 0.00 excellenceindeliveryaward -cv-charcoal_gold 0:0c373352626d 0.31 0.00 digitalsolutionsltd -cv-charcoal_gold 0:d398b29d3dbb 0.33 0.00 2023 -cv-charcoal_gold 0:92cb97e6b786 0.30 0.00 processimprovementinitiative -cv-charcoal_gold 0:6517b58450f7 0.34 0.00 increasedefficiencyby30% -cv-charcoal_gold 0:b1ab1e892617 0.36 0.00 2022 -cv-charcoal_gold 0:c2f5106fbd5a 0.33 0.00 topperformer -cv-charcoal_gold 0:058521fbf0d1 0.37 0.00 innovatechsystems -cv-charcoal_gold 0:3def82282260 0.30 -0.71 technicaltools -cv-charcoal_gold 0:eb04bd42c7fb 0.36 -1.19 microsoft365|jira|confluence|asa +cv-charcoal_gold 0:086c0e036e67 -0.25 0.09 2021–present +cv-charcoal_gold 0:eddc2d311872 -0.31 0.06 seniorprojectmanager +cv-charcoal_gold 0:243953e20dc4 -0.21 0.06 digitalsolutionsltd·london,uk +cv-charcoal_gold 0:7fde5861c84b -0.14 0.06 •managecross-functionalteamsofup +cv-charcoal_gold 0:80c76af1fe2a -0.12 0.06 •implementagilepracticesthatimpr +cv-charcoal_gold 0:b6bb33b79f44 -0.10 0.06 •buildstrongclientrelationshipsa +cv-charcoal_gold 0:6c39082d9294 -0.13 0.09 2019–2021 +cv-charcoal_gold 0:46df57ef8321 -0.09 0.06 innovatechsystems·london,uk +cv-charcoal_gold 0:271b01626043 -0.06 0.06 •delivered12+projectsacrossitand +cv-charcoal_gold 0:77dd7c2ad6ae -0.04 0.06 •monitoredbudgets,timelines,andr +cv-charcoal_gold 0:bf8278cd4edc -0.02 0.06 •identifiedrisksandimplementedmi +cv-charcoal_gold 0:2773f92777d7 0.00 0.06 •achieved98%on-timeprojectdelive +cv-charcoal_gold 0:ad564a6ee91d -0.03 0.09 2017–2019 +cv-charcoal_gold 0:e085ad3a0d32 -0.09 0.06 projectcoordinator +cv-charcoal_gold 0:6ac382583801 0.01 0.06 globalbusinessservices·london,uk +cv-charcoal_gold 0:77aec5bb6b7f 0.04 0.06 •supportedprojectmanagersinplann +cv-charcoal_gold 0:38dafe4a1765 0.06 0.06 •preparedreports,dashboards,andd +cv-charcoal_gold 0:5c95a9041b72 0.08 0.06 •coordinatedmeetingsandtrackedac +cv-charcoal_gold 0:f0d87e2131e2 0.10 0.06 •improvedinternalprocessesandpro +cv-charcoal_gold 0:e831beb04c00 0.01 0.14 certifications +cv-charcoal_gold 0:93a7ba535da0 0.07 0.10 pmp®certification +cv-charcoal_gold 0:0f9f6d10bfa3 0.11 0.10 projectmanagementinstitute +cv-charcoal_gold 0:73a2af8864fc 0.13 0.10 2020 +cv-charcoal_gold 0:73a2af8864fc#1 0.19 0.00 2020 +cv-charcoal_gold 0:043092900ed5 0.10 0.10 prince2®foundation +cv-charcoal_gold 0:544a764703d6 0.14 0.10 axelos +cv-charcoal_gold 0:023e33504ab9 0.16 0.10 2019 +cv-charcoal_gold 0:023e33504ab9#1 0.19 0.10 2019 +cv-charcoal_gold 0:83cd2e790f6a 0.13 0.10 agilepm®foundation +cv-charcoal_gold 0:0005e5872534 0.17 0.10 apmginternational +cv-charcoal_gold 0:6ee18b42fbf1 0.01 0.09 achievements +cv-charcoal_gold 0:3f06e4a3eb33 0.07 0.00 excellenceindeliveryaward +cv-charcoal_gold 0:0c373352626d 0.11 0.00 digitalsolutionsltd +cv-charcoal_gold 0:d398b29d3dbb 0.13 0.00 2023 +cv-charcoal_gold 0:92cb97e6b786 0.10 0.00 processimprovementinitiative +cv-charcoal_gold 0:6517b58450f7 0.14 0.00 increasedefficiencyby30% +cv-charcoal_gold 0:b1ab1e892617 0.16 0.00 2022 +cv-charcoal_gold 0:c2f5106fbd5a 0.13 0.00 topperformer +cv-charcoal_gold 0:058521fbf0d1 0.17 0.00 innovatechsystems +cv-charcoal_gold 0:3def82282260 0.10 -0.71 technicaltools +cv-charcoal_gold 0:eb04bd42c7fb 0.16 -1.19 microsoft365|jira|confluence|asa cv-classic_serif 0:8f1010120ed6 -0.15 2.60 jordanrivera cv-classic_serif 0:8d7a2cca3060 0.19 -0.52 +442055551000|jordan.rivera@exam cv-classic_serif 0:3c69d6bb4892 0.24 20.27 professionalprofile -cv-classic_serif 0:32c1cf49a2fe 0.14 0.10 skills -cv-classic_serif 0:873a24d153c8 0.11 0.10 languages:java21,kotlin,groovy,p -cv-classic_serif 0:05e907ef2b18 0.09 0.10 document&print:pdfbox,apachepoi( -cv-classic_serif 0:76656a8a6621 0.06 0.10 layoutengines:customdsldesign,se -cv-classic_serif 0:1cd141fef347 0.04 0.10 build&infrastructure:maven,gradl -cv-classic_serif 0:181ddda7f959 0.01 0.10 testing:junit5,assertj,pdfbox-ba -cv-classic_serif 0:c40c656d9558 -0.01 0.10 distribution:mavencentral,sonaty -cv-classic_serif 0:53e5e7c5a884 0.00 0.10 experience -cv-classic_serif 0:a76f47480818 0.01 0.10 seniorplatformengineer -cv-classic_serif 0:060300b18051 -0.02 0.26 2024-present -cv-classic_serif 0:f890faef907f -0.01 0.10 northwindsystems -cv-classic_serif 0:49faf14f1f56 -0.24 0.10 ledthereusabledocument-generatio -cv-classic_serif 0:6bd3f168e89e -0.25 0.10 maintenancetimeby70%byretiringpe -cv-classic_serif 0:daf65306b3b6 0.03 0.10 softwareengineer -cv-classic_serif 0:e7cc1822c6dc 0.00 1.12 2021-2024 -cv-classic_serif 0:998c1a985022 0.01 0.10 brightleaflabs -cv-classic_serif 0:e55664011cda -0.22 0.10 builtbackendservicesandproductio -cv-classic_serif 0:e80236b6d2b1 -0.23 0.10 itexttoacustomlayoutengine,elimi -cv-classic_serif 0:41bb54fbae8d 0.04 0.10 backendengineer -cv-classic_serif 0:3fa772117260 0.01 1.12 2019-2021 -cv-classic_serif 0:3fa772117260#1 0.03 1.12 2019-2021 -cv-classic_serif 0:ef148f221e31 0.02 0.10 helixprintco -cv-classic_serif 0:9d31a6bfbc69 -0.21 0.10 maintainedahigh-volumeinvoice-pr -cv-classic_serif 0:03af8a628309 -0.22 0.10 change. -cv-classic_serif 0:2577c0f557b2 0.05 0.10 projects -cv-classic_serif 0:0f2c67872251 0.06 0.10 graphcompose(java21,pdfbox,maven -cv-classic_serif 0:67593a76ef70 -0.21 0.10 declarativejavapdflayoutengine.s -cv-classic_serif 0:b9292cbd1454 -0.22 0.10 pipelinesforhiringtoolsandbillin -cv-classic_serif 0:d73d02174dc9 0.05 0.10 templatestudio(kotlin,composedes -cv-classic_serif 0:836e76daecbf 0.03 0.10 internaltoolforevaluatingcv,prop -cv-classic_serif 0:542ec793b5b1 0.05 0.10 layoutlint(java21,javaparser,spo -cv-classic_serif 0:dc31b6a18325 0.03 0.10 staticanalyserthatflagsfragileau -cv-classic_serif 0:ee180ea1e0a5 0.05 0.10 chromeforge(java,graphcompose,pa -cv-classic_serif 0:e7e62230eb1f 0.03 0.10 editorial-magazinedocumenttoolki -cv-classic_serif 0:68bf0109c6f8 0.05 0.10 education -cv-classic_serif 0:0ad1957d6bab 0.06 0.10 msccomputerscience -cv-classic_serif 0:47ce0218bbea 0.04 0.10 universityofmanchester -cv-classic_serif 0:2ffe115b06e5 0.06 0.10 distinction.thesis:composablelay -cv-classic_serif 0:b6749d0b616b 0.08 0.10 bscsoftwareengineering -cv-classic_serif 0:30f9262640a0 0.05 1.12 2015-2019 +cv-classic_serif 0:32c1cf49a2fe 0.39 0.10 skills +cv-classic_serif 0:873a24d153c8 0.36 0.10 languages:java21,kotlin,groovy,p +cv-classic_serif 0:05e907ef2b18 0.34 0.10 document&print:pdfbox,apachepoi( +cv-classic_serif 0:76656a8a6621 0.31 0.10 layoutengines:customdsldesign,se +cv-classic_serif 0:1cd141fef347 0.29 0.10 build&infrastructure:maven,gradl +cv-classic_serif 0:181ddda7f959 0.26 0.10 testing:junit5,assertj,pdfbox-ba +cv-classic_serif 0:c40c656d9558 0.24 0.10 distribution:mavencentral,sonaty +cv-classic_serif 0:53e5e7c5a884 0.25 0.10 experience +cv-classic_serif 0:a76f47480818 0.26 0.10 seniorplatformengineer +cv-classic_serif 0:060300b18051 0.23 0.26 2024-present +cv-classic_serif 0:f890faef907f 0.24 0.10 northwindsystems +cv-classic_serif 0:49faf14f1f56 0.01 0.10 ledthereusabledocument-generatio +cv-classic_serif 0:6bd3f168e89e 0.00 0.10 maintenancetimeby70%byretiringpe +cv-classic_serif 0:daf65306b3b6 0.28 0.10 softwareengineer +cv-classic_serif 0:e7cc1822c6dc 0.25 1.12 2021-2024 +cv-classic_serif 0:998c1a985022 0.26 0.10 brightleaflabs +cv-classic_serif 0:e55664011cda 0.03 0.10 builtbackendservicesandproductio +cv-classic_serif 0:e80236b6d2b1 0.02 0.10 itexttoacustomlayoutengine,elimi +cv-classic_serif 0:41bb54fbae8d 0.29 0.10 backendengineer +cv-classic_serif 0:3fa772117260 0.26 1.12 2019-2021 +cv-classic_serif 0:3fa772117260#1 0.28 1.12 2019-2021 +cv-classic_serif 0:ef148f221e31 0.27 0.10 helixprintco +cv-classic_serif 0:9d31a6bfbc69 0.04 0.10 maintainedahigh-volumeinvoice-pr +cv-classic_serif 0:03af8a628309 0.03 0.10 change. +cv-classic_serif 0:2577c0f557b2 0.30 0.10 projects +cv-classic_serif 0:0f2c67872251 0.31 0.10 graphcompose(java21,pdfbox,maven +cv-classic_serif 0:67593a76ef70 0.04 0.10 declarativejavapdflayoutengine.s +cv-classic_serif 0:b9292cbd1454 0.03 0.10 pipelinesforhiringtoolsandbillin +cv-classic_serif 0:d73d02174dc9 0.30 0.10 templatestudio(kotlin,composedes +cv-classic_serif 0:836e76daecbf 0.28 0.10 internaltoolforevaluatingcv,prop +cv-classic_serif 0:542ec793b5b1 0.30 0.10 layoutlint(java21,javaparser,spo +cv-classic_serif 0:dc31b6a18325 0.28 0.10 staticanalyserthatflagsfragileau +cv-classic_serif 0:ee180ea1e0a5 0.30 0.10 chromeforge(java,graphcompose,pa +cv-classic_serif 0:e7e62230eb1f 0.28 0.10 editorial-magazinedocumenttoolki +cv-classic_serif 0:68bf0109c6f8 0.30 0.10 education +cv-classic_serif 0:0ad1957d6bab 0.31 0.10 msccomputerscience +cv-classic_serif 0:47ce0218bbea 0.29 0.10 universityofmanchester +cv-classic_serif 0:2ffe115b06e5 0.31 0.10 distinction.thesis:composablelay +cv-classic_serif 0:b6749d0b616b 0.33 0.10 bscsoftwareengineering +cv-classic_serif 0:30f9262640a0 0.30 1.12 2015-2019 cv-classic_serif 1:89ad9656f393 0.16 0.10 imperialcollegelondon cv-classic_serif 1:baa173b4a82e 0.18 0.10 first-classhonours.specialisatio cv-classic_serif 1:6d3d5673c39f 0.20 0.10 oraclejavacertification @@ -332,34 +332,34 @@ cv-compact_mono 0:8051a4b5e34f 0.84 0.10 opensource:maintainerofgraphcomp cv-compact_mono 0:08c2e869a75b 0.85 0.10 regularcontributortopdfboxissuet cv-compact_mono 0:12dcd1343975 0.86 0.10 speaking:jvmsummit2024,devoxxuk2 cv-compact_mono 0:3aea7f90f8ed 0.87 0.10 —bothondeclarativedocumentlayout -cv-compact_mono 0:1900eab6c028 0.44 0.09 profile -cv-compact_mono 0:3828b9718a0d -0.15 0.09 platformengineerwith10+yearsbuil -cv-compact_mono 0:f6b5e93ccadd -0.14 0.09 engines,anddeveloper-facingtempl -cv-compact_mono 0:927ef106776a -0.13 0.09 semanticauthoringdsls,andturning -cv-compact_mono 0:330fcb75ed52 -0.12 0.09 librariesthatscale. -cv-compact_mono 0:53e5e7c5a884 0.16 0.09 experience -cv-compact_mono 0:c9efb118bfda -0.19 0.09 seniorplatformengineer,northwind -cv-compact_mono 0:64c4b52dceb1 -0.39 0.09 ledthereusabledocument-generatio -cv-compact_mono 0:1f193cd1d987 -0.37 0.09 productteams.reducedtemplatemain -cv-compact_mono 0:9ccc3e904e5a -0.35 0.09 favourofonecanonicalengine. -cv-compact_mono 0:e21e4e47835a -0.14 0.09 softwareengineer,brightleaflabs| -cv-compact_mono 0:0cdd48f05f9d -0.34 0.09 builtbackendservicesandproductio -cv-compact_mono 0:e48f1e2c853d -0.32 0.09 permonth.drovethemigrationfromit -cv-compact_mono 0:b78a9a72ca9a -0.30 0.09 andcuttingp99renderlatencyfrom1. -cv-compact_mono 0:9f5d87c00954 -0.09 0.09 backendengineer,helixprintco|201 -cv-compact_mono 0:a485c37fe7ea -0.29 0.09 maintainedahigh-volumeinvoice-pr -cv-compact_mono 0:5a136b6b9d8c -0.27 0.09 testharnessthatgatedeverytemplat -cv-compact_mono 0:d94eccbb1fbe -0.01 0.09 selectedprojects -cv-compact_mono 0:0059a3aac61e -0.56 0.09 graphcompose(java21,pdfbox,maven -cv-compact_mono 0:18b7f8c840e4 -0.53 0.09 dsl,slot-basedtemplates,snapshot -cv-compact_mono 0:d36f78e88fe0 -0.49 0.09 forhiringtoolsandbillingsystems. -cv-compact_mono 0:55e119878845 -0.48 0.09 templatestudio(kotlin,composedes -cv-compact_mono 0:c7b83853442b -0.45 0.09 proposal,andinvoiceoutputacross1 -cv-compact_mono 0:6b844249c695 -0.41 0.09 freezing. -cv-compact_mono 0:ab89138286bb -0.40 0.09 layoutlint(java21,javaparser,spo -cv-compact_mono 0:2c506ce69aa6 -0.37 0.09 nestedrows,untypedoffsets,implic -cv-compact_mono 0:6793d28e9783 -0.36 0.09 chromeforge(java,graphcompose,pa -cv-compact_mono 0:e3cfea265b3b -0.33 0.09 graphcompose:cinematiccovers,pul +cv-compact_mono 0:1900eab6c028 0.24 0.09 profile +cv-compact_mono 0:3828b9718a0d -0.35 0.09 platformengineerwith10+yearsbuil +cv-compact_mono 0:f6b5e93ccadd -0.34 0.09 engines,anddeveloper-facingtempl +cv-compact_mono 0:927ef106776a -0.33 0.09 semanticauthoringdsls,andturning +cv-compact_mono 0:330fcb75ed52 -0.32 0.09 librariesthatscale. +cv-compact_mono 0:53e5e7c5a884 0.31 0.09 experience +cv-compact_mono 0:c9efb118bfda -0.04 0.09 seniorplatformengineer,northwind +cv-compact_mono 0:64c4b52dceb1 -0.24 0.09 ledthereusabledocument-generatio +cv-compact_mono 0:1f193cd1d987 -0.22 0.09 productteams.reducedtemplatemain +cv-compact_mono 0:9ccc3e904e5a -0.20 0.09 favourofonecanonicalengine. +cv-compact_mono 0:e21e4e47835a 0.01 0.09 softwareengineer,brightleaflabs| +cv-compact_mono 0:0cdd48f05f9d -0.19 0.09 builtbackendservicesandproductio +cv-compact_mono 0:e48f1e2c853d -0.17 0.09 permonth.drovethemigrationfromit +cv-compact_mono 0:b78a9a72ca9a -0.15 0.09 andcuttingp99renderlatencyfrom1. +cv-compact_mono 0:9f5d87c00954 0.06 0.09 backendengineer,helixprintco|201 +cv-compact_mono 0:a485c37fe7ea -0.14 0.09 maintainedahigh-volumeinvoice-pr +cv-compact_mono 0:5a136b6b9d8c -0.12 0.09 testharnessthatgatedeverytemplat +cv-compact_mono 0:d94eccbb1fbe 0.49 0.09 selectedprojects +cv-compact_mono 0:0059a3aac61e -0.06 0.09 graphcompose(java21,pdfbox,maven +cv-compact_mono 0:18b7f8c840e4 -0.03 0.09 dsl,slot-basedtemplates,snapshot +cv-compact_mono 0:d36f78e88fe0 0.01 0.09 forhiringtoolsandbillingsystems. +cv-compact_mono 0:55e119878845 0.02 0.09 templatestudio(kotlin,composedes +cv-compact_mono 0:c7b83853442b 0.05 0.09 proposal,andinvoiceoutputacross1 +cv-compact_mono 0:6b844249c695 0.09 0.09 freezing. +cv-compact_mono 0:ab89138286bb 0.10 0.09 layoutlint(java21,javaparser,spo +cv-compact_mono 0:2c506ce69aa6 0.13 0.09 nestedrows,untypedoffsets,implic +cv-compact_mono 0:6793d28e9783 0.14 0.09 chromeforge(java,graphcompose,pa +cv-compact_mono 0:e3cfea265b3b 0.17 0.09 graphcompose:cinematiccovers,pul cv-editorial_blue 0:8f1010120ed6 0.45 0.12 jordanrivera cv-editorial_blue 0:2d58f0cadc2d 0.22 0.13 platformengineer cv-editorial_blue 0:1b28eb6a9a2e 0.14 0.13 +442055551000-london,uk @@ -449,56 +449,56 @@ cv-engineering_resume 0:89674e6f130e -0.20 15.34 +442055551000 cv-engineering_resume 0:e0f850305ded -0.19 15.20 jordan.rivera@example.com cv-engineering_resume 0:84308bea4540 -0.18 15.95 linkedin cv-engineering_resume 0:c0b0109d9439 -0.17 15.85 github -cv-engineering_resume 0:32c1cf49a2fe -0.50 0.10 skills -cv-engineering_resume 0:873a24d153c8 -0.44 0.10 languages:java21,kotlin,groovy,p -cv-engineering_resume 0:db84150190bb -0.63 0.10 document&print:pdfbox,apachepoi -cv-engineering_resume 0:69d03fef7130 -0.62 0.10 (docx/xlsx),itext,postscript,icc -cv-engineering_resume 0:d52fd337f016 -0.61 0.10 profiles -cv-engineering_resume 0:f93032b34754 -0.60 0.10 layoutengines:customdsldesign,se -cv-engineering_resume 0:2d6fa255ba3a -0.59 0.10 layouttrees,pagination,snapshott -cv-engineering_resume 0:f274537aaf2c -0.58 0.10 regression -cv-engineering_resume 0:45fcec9fa26d -0.57 0.10 build&infrastructure:maven,gradl -cv-engineering_resume 0:33ddf84f4bab -0.56 0.10 actions,jitpack,docker -cv-engineering_resume 0:af23376e2ec2 -0.55 0.10 testing:junit5,assertj,pdfbox-ba -cv-engineering_resume 0:a8c30cabf363 -0.54 0.10 diff,layout-graphsnapshots,mutat -cv-engineering_resume 0:7c093617a679 -0.53 0.10 (pitest) -cv-engineering_resume 0:11ca7190fe83 -0.52 0.10 distribution:mavencentral,sonaty -cv-engineering_resume 0:768ad260251b -0.51 0.10 gpgsigning,jitpack,semanticversi -cv-engineering_resume 0:d43c8bd5797a -0.50 0.10 discipline -cv-engineering_resume 0:68bf0109c6f8 -0.38 0.10 education -cv-engineering_resume 0:5f9c672fafaf -0.32 0.10 msccomputerscience/2019-2021 -cv-engineering_resume 0:141310eca6fb -0.31 0.10 bscsoftwareengineering/2015-2019 -cv-engineering_resume 0:608c03298f47 -0.30 0.10 oraclejavacertification/2023-202 -cv-engineering_resume 0:41ffd8b76afc -0.38 0.10 details -cv-engineering_resume 0:ecc25e73b19b -0.52 0.10 languages:english(fluent),german -cv-engineering_resume 0:ac7f0ee6a49e -0.51 0.10 (intermediate),spanish(basic) -cv-engineering_resume 0:970ca9d789c2 -0.50 0.10 workeligibility:eligibletoworkin -cv-engineering_resume 0:0735680e2596 -0.49 0.10 theeu -cv-engineering_resume 0:e8256e23459a -1.55 0.10 engineeringprofile -cv-engineering_resume 0:e9b75496bfb4 -1.65 0.10 platformengineerwith10+yearsbuil -cv-engineering_resume 0:866be9f7a132 -1.65 0.10 developer-facingtemplatesystems. -cv-engineering_resume 0:82c1650fbfe8 -1.65 0.10 dsls,andturningbrittleproduction -cv-engineering_resume 0:53e5e7c5a884 -1.55 0.10 experience -cv-engineering_resume 0:4977534824cc -1.46 0.10 seniorplatformengineer/2024-pres -cv-engineering_resume 0:f890faef907f -1.42 0.10 northwindsystems -cv-engineering_resume 0:0bf7eb0b1058 -1.66 0.10 ledthereusabledocument-generatio -cv-engineering_resume 0:d69cae607226 -1.64 0.10 teams.reducedtemplatemaintenance -cv-engineering_resume 0:bdea17333528 -1.62 0.10 engine. -cv-engineering_resume 0:7033b2988e4d -1.42 0.10 softwareengineer/2021-2024 -cv-engineering_resume 0:998c1a985022 -1.38 0.10 brightleaflabs -cv-engineering_resume 0:e77e909f6ff5 -1.62 0.10 builtbackendservicesandproductio -cv-engineering_resume 0:97c59b2fdb55 -1.60 0.10 drovethemigrationfromitexttoacus -cv-engineering_resume 0:2c2b19cf214d -1.58 0.10 latencyfrom1.4sto380ms. -cv-engineering_resume 0:8b5abdc8c0d7 -1.48 0.10 technicalevidence -cv-engineering_resume 0:e2fbf67cb588 -0.99 0.05 graphcompose(java21,pdfbox,maven -cv-engineering_resume 0:eb5950729749 -1.13 0.05 templates,snapshottesting.powers -cv-engineering_resume 0:81c8132f9792 -1.21 0.05 systems.(opensource) -cv-engineering_resume 0:643428f0ebf8 -1.02 0.05 templatestudio(kotlin,composedes -cv-engineering_resume 0:c259a0e7581e -1.31 0.05 invoiceoutputacross14designprese -cv-engineering_resume 0:c944ee08a5bf -1.12 0.05 layoutlint(java21,javaparser,spo -cv-engineering_resume 0:2d80d05697ad -1.41 0.05 untypedoffsets,implicitpagebreak -cv-engineering_resume 0:6793d28e9783 -1.22 0.05 chromeforge(java,graphcompose,pa -cv-engineering_resume 0:e3cfea265b3b -1.51 0.05 graphcompose:cinematiccovers,pul +cv-engineering_resume 0:32c1cf49a2fe -0.25 0.10 skills +cv-engineering_resume 0:873a24d153c8 -0.19 0.10 languages:java21,kotlin,groovy,p +cv-engineering_resume 0:db84150190bb -0.38 0.10 document&print:pdfbox,apachepoi +cv-engineering_resume 0:69d03fef7130 -0.37 0.10 (docx/xlsx),itext,postscript,icc +cv-engineering_resume 0:d52fd337f016 -0.36 0.10 profiles +cv-engineering_resume 0:f93032b34754 -0.35 0.10 layoutengines:customdsldesign,se +cv-engineering_resume 0:2d6fa255ba3a -0.34 0.10 layouttrees,pagination,snapshott +cv-engineering_resume 0:f274537aaf2c -0.33 0.10 regression +cv-engineering_resume 0:45fcec9fa26d -0.32 0.10 build&infrastructure:maven,gradl +cv-engineering_resume 0:33ddf84f4bab -0.31 0.10 actions,jitpack,docker +cv-engineering_resume 0:af23376e2ec2 -0.30 0.10 testing:junit5,assertj,pdfbox-ba +cv-engineering_resume 0:a8c30cabf363 -0.29 0.10 diff,layout-graphsnapshots,mutat +cv-engineering_resume 0:7c093617a679 -0.28 0.10 (pitest) +cv-engineering_resume 0:11ca7190fe83 -0.27 0.10 distribution:mavencentral,sonaty +cv-engineering_resume 0:768ad260251b -0.26 0.10 gpgsigning,jitpack,semanticversi +cv-engineering_resume 0:d43c8bd5797a -0.25 0.10 discipline +cv-engineering_resume 0:68bf0109c6f8 -0.13 0.10 education +cv-engineering_resume 0:5f9c672fafaf -0.07 0.10 msccomputerscience/2019-2021 +cv-engineering_resume 0:141310eca6fb -0.06 0.10 bscsoftwareengineering/2015-2019 +cv-engineering_resume 0:608c03298f47 -0.05 0.10 oraclejavacertification/2023-202 +cv-engineering_resume 0:41ffd8b76afc -0.13 0.10 details +cv-engineering_resume 0:ecc25e73b19b -0.27 0.10 languages:english(fluent),german +cv-engineering_resume 0:ac7f0ee6a49e -0.26 0.10 (intermediate),spanish(basic) +cv-engineering_resume 0:970ca9d789c2 -0.25 0.10 workeligibility:eligibletoworkin +cv-engineering_resume 0:0735680e2596 -0.24 0.10 theeu +cv-engineering_resume 0:e8256e23459a -0.30 0.10 engineeringprofile +cv-engineering_resume 0:e9b75496bfb4 -0.40 0.10 platformengineerwith10+yearsbuil +cv-engineering_resume 0:866be9f7a132 -0.40 0.10 developer-facingtemplatesystems. +cv-engineering_resume 0:82c1650fbfe8 -0.40 0.10 dsls,andturningbrittleproduction +cv-engineering_resume 0:53e5e7c5a884 -0.30 0.10 experience +cv-engineering_resume 0:4977534824cc -0.21 0.10 seniorplatformengineer/2024-pres +cv-engineering_resume 0:f890faef907f -0.17 0.10 northwindsystems +cv-engineering_resume 0:0bf7eb0b1058 -0.41 0.10 ledthereusabledocument-generatio +cv-engineering_resume 0:d69cae607226 -0.39 0.10 teams.reducedtemplatemaintenance +cv-engineering_resume 0:bdea17333528 -0.37 0.10 engine. +cv-engineering_resume 0:7033b2988e4d -0.17 0.10 softwareengineer/2021-2024 +cv-engineering_resume 0:998c1a985022 -0.13 0.10 brightleaflabs +cv-engineering_resume 0:e77e909f6ff5 -0.37 0.10 builtbackendservicesandproductio +cv-engineering_resume 0:97c59b2fdb55 -0.35 0.10 drovethemigrationfromitexttoacus +cv-engineering_resume 0:2c2b19cf214d -0.33 0.10 latencyfrom1.4sto380ms. +cv-engineering_resume 0:8b5abdc8c0d7 -0.23 0.10 technicalevidence +cv-engineering_resume 0:e2fbf67cb588 0.41 0.05 graphcompose(java21,pdfbox,maven +cv-engineering_resume 0:eb5950729749 0.27 0.05 templates,snapshottesting.powers +cv-engineering_resume 0:81c8132f9792 0.19 0.05 systems.(opensource) +cv-engineering_resume 0:643428f0ebf8 0.68 0.05 templatestudio(kotlin,composedes +cv-engineering_resume 0:c259a0e7581e 0.39 0.05 invoiceoutputacross14designprese +cv-engineering_resume 0:c944ee08a5bf 0.88 0.05 layoutlint(java21,javaparser,spo +cv-engineering_resume 0:2d80d05697ad 0.59 0.05 untypedoffsets,implicitpagebreak +cv-engineering_resume 0:6793d28e9783 1.08 0.05 chromeforge(java,graphcompose,pa +cv-engineering_resume 0:e3cfea265b3b 0.79 0.05 graphcompose:cinematiccovers,pul cv-executive 0:8f1010120ed6 -0.50 0.10 jordanrivera cv-executive 0:89ff05847e96 -0.28 0.10 london,uk|+442055551000 cv-executive 0:8817bf9310b6 -0.30 0.10 jordan.rivera@example.com|linked @@ -645,46 +645,46 @@ cv-midnight_navy 0:200b36afcfde -0.09 0.09 hubspotacademy cv-midnight_navy 0:1bea20e1df19 -0.11 0.09 2021 cv-minimal_underlined 0:8f1010120ed6 0.46 2.20 jordanrivera cv-minimal_underlined 0:8d7a2cca3060 0.18 0.12 +442055551000|jordan.rivera@exam -cv-minimal_underlined 0:b944906ed84c -0.11 0.10 professionalsummary -cv-minimal_underlined 0:80cc87fdc4c4 -0.72 0.10 platformengineerwith10+yearsbuil -cv-minimal_underlined 0:bddc0bd093ce -0.72 0.10 systems.specialisedinhigh-throug -cv-minimal_underlined 0:95a43d7b3df0 -0.71 0.10 snapshot-testedlibrariesthatscal -cv-minimal_underlined 0:5f94c50dc5bf -0.38 0.10 technicalskills -cv-minimal_underlined 0:eea537278f83 -0.70 0.10 •languages:java21,kotlin,groovy, -cv-minimal_underlined 0:9c2cd7231a53 -0.69 0.10 •document&print:pdfbox,apachepoi -cv-minimal_underlined 0:7bf8639ec5d3 -0.69 0.10 •layoutengines:customdsldesign,s -cv-minimal_underlined 0:8e66776d28d7 -0.68 0.10 •build&infrastructure:maven,grad -cv-minimal_underlined 0:1ed4fc7d7768 -0.68 0.10 •testing:junit5,assertj,pdfbox-b -cv-minimal_underlined 0:26671c309eb9 -0.67 0.10 •distribution:mavencentral,sonat -cv-minimal_underlined 0:68bf0109c6f8 -0.64 0.10 education -cv-minimal_underlined 0:0ad1957d6bab -0.93 0.10 msccomputerscience -cv-minimal_underlined 0:3fa772117260 -0.97 -0.76 2019-2021 -cv-minimal_underlined 0:47ce0218bbea -0.94 0.10 universityofmanchester -cv-minimal_underlined 0:2ffe115b06e5 -0.93 0.10 distinction.thesis:composablelay -cv-minimal_underlined 0:b6749d0b616b -0.90 0.10 bscsoftwareengineering -cv-minimal_underlined 0:30f9262640a0 -0.93 -0.76 2015-2019 -cv-minimal_underlined 0:89ad9656f393 -0.91 0.10 imperialcollegelondon -cv-minimal_underlined 0:baa173b4a82e -0.89 0.10 first-classhonours.specialisatio -cv-minimal_underlined 0:6d3d5673c39f -0.86 0.10 oraclejavacertification -cv-minimal_underlined 0:d40b22f00acb -0.90 -0.76 2023-2024 -cv-minimal_underlined 0:2669e1f6d55c -0.87 0.10 professionaltrack -cv-minimal_underlined 0:3857373829c1 -0.86 0.10 java17platformdeep-dive:records, -cv-minimal_underlined 0:2577c0f557b2 -0.83 0.10 projects -cv-minimal_underlined 0:b2b029995203 -1.14 0.10 •graphcompose(java21,pdfbox,mave -cv-minimal_underlined 0:67593a76ef70 -1.44 0.11 declarativejavapdflayoutengine.s -cv-minimal_underlined 0:b9292cbd1454 -1.43 0.11 pipelinesforhiringtoolsandbillin -cv-minimal_underlined 0:1b50bb81df5a -1.13 0.10 •templatestudio(kotlin,composede -cv-minimal_underlined 0:7127a108c33c -1.42 0.11 internaltoolforevaluatingcv,prop -cv-minimal_underlined 0:6b844249c695 -1.42 0.11 freezing. -cv-minimal_underlined 0:25cdca2beb8b -1.11 0.10 •layoutlint(java21,javaparser,sp -cv-minimal_underlined 0:7488006d7864 -1.41 0.11 staticanalyserthatflagsfragileau -cv-minimal_underlined 0:c4d0c415b4f8 -1.40 0.11 production. -cv-minimal_underlined 0:fb1927f88597 -1.10 0.10 •chromeforge(java,graphcompose,p -cv-minimal_underlined 0:e7e62230eb1f -1.09 0.11 editorial-magazinedocumenttoolki -cv-minimal_underlined 0:c2f296ef30a3 -1.06 0.10 professionalexperience -cv-minimal_underlined 0:a76f47480818 -1.35 0.10 seniorplatformengineer -cv-minimal_underlined 0:060300b18051 -1.39 0.01 2024-present -cv-minimal_underlined 0:f890faef907f -1.36 0.10 northwindsystems +cv-minimal_underlined 0:b944906ed84c 0.24 0.10 professionalsummary +cv-minimal_underlined 0:80cc87fdc4c4 -0.02 0.10 platformengineerwith10+yearsbuil +cv-minimal_underlined 0:bddc0bd093ce -0.02 0.10 systems.specialisedinhigh-throug +cv-minimal_underlined 0:95a43d7b3df0 -0.01 0.10 snapshot-testedlibrariesthatscal +cv-minimal_underlined 0:5f94c50dc5bf 0.32 0.10 technicalskills +cv-minimal_underlined 0:eea537278f83 0.35 0.10 •languages:java21,kotlin,groovy, +cv-minimal_underlined 0:9c2cd7231a53 0.36 0.10 •document&print:pdfbox,apachepoi +cv-minimal_underlined 0:7bf8639ec5d3 0.36 0.10 •layoutengines:customdsldesign,s +cv-minimal_underlined 0:8e66776d28d7 0.37 0.10 •build&infrastructure:maven,grad +cv-minimal_underlined 0:1ed4fc7d7768 0.37 0.10 •testing:junit5,assertj,pdfbox-b +cv-minimal_underlined 0:26671c309eb9 0.38 0.10 •distribution:mavencentral,sonat +cv-minimal_underlined 0:68bf0109c6f8 0.41 0.10 education +cv-minimal_underlined 0:0ad1957d6bab 0.47 0.10 msccomputerscience +cv-minimal_underlined 0:3fa772117260 0.43 -0.76 2019-2021 +cv-minimal_underlined 0:47ce0218bbea 0.46 0.10 universityofmanchester +cv-minimal_underlined 0:2ffe115b06e5 0.47 0.10 distinction.thesis:composablelay +cv-minimal_underlined 0:b6749d0b616b 0.50 0.10 bscsoftwareengineering +cv-minimal_underlined 0:30f9262640a0 0.47 -0.76 2015-2019 +cv-minimal_underlined 0:89ad9656f393 0.49 0.10 imperialcollegelondon +cv-minimal_underlined 0:baa173b4a82e 0.51 0.10 first-classhonours.specialisatio +cv-minimal_underlined 0:6d3d5673c39f 0.54 0.10 oraclejavacertification +cv-minimal_underlined 0:d40b22f00acb 0.50 -0.76 2023-2024 +cv-minimal_underlined 0:2669e1f6d55c 0.53 0.10 professionaltrack +cv-minimal_underlined 0:3857373829c1 0.54 0.10 java17platformdeep-dive:records, +cv-minimal_underlined 0:2577c0f557b2 0.57 0.10 projects +cv-minimal_underlined 0:b2b029995203 0.61 0.10 •graphcompose(java21,pdfbox,mave +cv-minimal_underlined 0:67593a76ef70 0.31 0.11 declarativejavapdflayoutengine.s +cv-minimal_underlined 0:b9292cbd1454 0.32 0.11 pipelinesforhiringtoolsandbillin +cv-minimal_underlined 0:1b50bb81df5a 0.62 0.10 •templatestudio(kotlin,composede +cv-minimal_underlined 0:7127a108c33c 0.33 0.11 internaltoolforevaluatingcv,prop +cv-minimal_underlined 0:6b844249c695 0.33 0.11 freezing. +cv-minimal_underlined 0:25cdca2beb8b 0.64 0.10 •layoutlint(java21,javaparser,sp +cv-minimal_underlined 0:7488006d7864 0.34 0.11 staticanalyserthatflagsfragileau +cv-minimal_underlined 0:c4d0c415b4f8 0.35 0.11 production. +cv-minimal_underlined 0:fb1927f88597 0.65 0.10 •chromeforge(java,graphcompose,p +cv-minimal_underlined 0:e7e62230eb1f 0.66 0.11 editorial-magazinedocumenttoolki +cv-minimal_underlined 0:c2f296ef30a3 0.69 0.10 professionalexperience +cv-minimal_underlined 0:a76f47480818 0.75 0.10 seniorplatformengineer +cv-minimal_underlined 0:060300b18051 0.71 0.01 2024-present +cv-minimal_underlined 0:f890faef907f 0.74 0.10 northwindsystems cv-minimal_underlined 1:49faf14f1f56 -0.13 0.10 ledthereusabledocument-generatio cv-minimal_underlined 1:6bd3f168e89e -0.13 0.10 maintenancetimeby70%byretiringpe cv-minimal_underlined 1:daf65306b3b6 0.20 0.10 softwareengineer @@ -698,10 +698,10 @@ cv-minimal_underlined 1:ef148f221e31 0.23 0.10 helixprintco cv-minimal_underlined 1:9d31a6bfbc69 -0.05 0.10 maintainedahigh-volumeinvoice-pr cv-minimal_underlined 1:03af8a628309 -0.05 0.10 change. cv-minimal_underlined 1:676dfdd56ad2 0.28 0.10 additionalinformation -cv-minimal_underlined 1:f20997652453 -0.03 0.10 languages:english(fluent),german -cv-minimal_underlined 1:ec9d3622395e -0.03 0.10 workeligibility:eligibletoworkin -cv-minimal_underlined 1:dd20ae01c3cf -0.02 0.10 opensource:maintainerofgraphcomp -cv-minimal_underlined 1:33c35e9d236d -0.02 0.10 speaking:jvmsummit2024,devoxxuk2 +cv-minimal_underlined 1:f20997652453 0.32 0.10 languages:english(fluent),german +cv-minimal_underlined 1:ec9d3622395e 0.32 0.10 workeligibility:eligibletoworkin +cv-minimal_underlined 1:dd20ae01c3cf 0.33 0.10 opensource:maintainerofgraphcomp +cv-minimal_underlined 1:33c35e9d236d 0.33 0.10 speaking:jvmsummit2024,devoxxuk2 cv-mint_editorial 0:8f1010120ed6 -1.30 2.33 jordanrivera cv-mint_editorial 0:2d58f0cadc2d -0.27 0.12 platformengineer cv-mint_editorial 0:093e7d5fdbaa -0.71 0.10 contact @@ -764,57 +764,57 @@ cv-mint_editorial 1:1081945512b1 0.39 0.07 authoredthecompliancetestharness cv-modern_professional 0:8f1010120ed6 0.00 0.16 jordanrivera cv-modern_professional 0:89ff05847e96 0.14 0.16 london,uk|+442055551000 cv-modern_professional 0:8817bf9310b6 0.11 0.10 jordan.rivera@example.com|linked -cv-modern_professional 0:b944906ed84c 0.01 0.10 professionalsummary -cv-modern_professional 0:6fbdc8b79878 -0.42 0.10 platformengineerwith10+yearsbuil -cv-modern_professional 0:5f94c50dc5bf 0.01 0.10 technicalskills -cv-modern_professional 0:eea537278f83 -0.12 0.10 •languages:java21,kotlin,groovy, -cv-modern_professional 0:9c2cd7231a53 -0.12 0.10 •document&print:pdfbox,apachepoi -cv-modern_professional 0:7bf8639ec5d3 -0.12 0.10 •layoutengines:customdsldesign,s -cv-modern_professional 0:8e66776d28d7 -0.12 0.10 •build&infrastructure:maven,grad -cv-modern_professional 0:1ed4fc7d7768 -0.12 0.10 •testing:junit5,assertj,pdfbox-b -cv-modern_professional 0:26671c309eb9 -0.12 0.10 •distribution:mavencentral,sonat -cv-modern_professional 0:68bf0109c6f8 0.02 0.10 education -cv-modern_professional 0:0ad1957d6bab -0.12 0.10 msccomputerscience -cv-modern_professional 0:3fa772117260 -0.11 0.18 2019-2021 -cv-modern_professional 0:3fa772117260#1 -0.10 0.18 2019-2021 -cv-modern_professional 0:47ce0218bbea -0.17 0.10 universityofmanchester -cv-modern_professional 0:2ffe115b06e5 -0.11 0.10 distinction.thesis:composablelay -cv-modern_professional 0:b6749d0b616b -0.12 0.10 bscsoftwareengineering -cv-modern_professional 0:30f9262640a0 -0.11 0.18 2015-2019 -cv-modern_professional 0:89ad9656f393 -0.17 0.10 imperialcollegelondon -cv-modern_professional 0:baa173b4a82e -0.11 0.10 first-classhonours.specialisatio -cv-modern_professional 0:6d3d5673c39f -0.12 0.10 oraclejavacertification -cv-modern_professional 0:d40b22f00acb -0.11 0.18 2023-2024 -cv-modern_professional 0:2669e1f6d55c -0.17 0.10 professionaltrack -cv-modern_professional 0:3857373829c1 -0.11 0.10 java17platformdeep-dive:records, -cv-modern_professional 0:2577c0f557b2 0.02 0.10 projects -cv-modern_professional 0:b2b029995203 -0.11 0.10 •graphcompose(java21,pdfbox,mave -cv-modern_professional 0:dd39d2ff3520 -0.41 0.10 declarativejavapdflayoutengine.s -cv-modern_professional 0:9ecaa6df6d41 -0.41 0.10 invoice/proposalpipelinesforhiri -cv-modern_professional 0:1b50bb81df5a -0.11 0.10 •templatestudio(kotlin,composede -cv-modern_professional 0:18eec9e76e2d -0.41 0.10 internaltoolforevaluatingcv,prop -cv-modern_professional 0:6bc2807453c6 -0.41 0.10 baselinefreezing. -cv-modern_professional 0:25cdca2beb8b -0.11 0.10 •layoutlint(java21,javaparser,sp -cv-modern_professional 0:cc2850ddd8ba -0.41 0.10 staticanalyserthatflagsfragileau -cv-modern_professional 0:7b985a1d2b08 -0.41 0.10 shiptoproduction. -cv-modern_professional 0:fb1927f88597 -0.11 0.10 •chromeforge(java,graphcompose,p -cv-modern_professional 0:cda7db6c6ea6 -0.41 0.10 editorial-magazinedocumenttoolki -cv-modern_professional 0:fe63fe18585a -0.41 0.10 callouts. -cv-modern_professional 0:c2f296ef30a3 0.03 0.10 professionalexperience -cv-modern_professional 0:a76f47480818 -0.11 0.10 seniorplatformengineer -cv-modern_professional 0:060300b18051 -0.10 0.15 2024-present -cv-modern_professional 0:f890faef907f -0.16 0.10 northwindsystems -cv-modern_professional 0:a6525dacbac7 -0.40 0.10 ledthereusabledocument-generatio -cv-modern_professional 0:15e3905f4890 -0.40 0.10 reducedtemplatemaintenancetimeby -cv-modern_professional 0:daf65306b3b6 -0.11 0.10 softwareengineer -cv-modern_professional 0:e7cc1822c6dc -0.10 0.18 2021-2024 -cv-modern_professional 0:998c1a985022 -0.16 0.10 brightleaflabs -cv-modern_professional 0:e86691b0219f -0.40 0.10 builtbackendservicesandproductio -cv-modern_professional 0:4ec57434564a -0.40 0.10 migrationfromitexttoacustomlayou -cv-modern_professional 0:41bb54fbae8d -0.11 0.10 backendengineer -cv-modern_professional 0:ef148f221e31 -0.16 0.10 helixprintco -cv-modern_professional 0:a32c7f2401d9 -0.40 0.10 maintainedahigh-volumeinvoice-pr -cv-modern_professional 0:7068c1d7034b -0.40 0.10 everytemplatechange. +cv-modern_professional 0:b944906ed84c 0.36 0.10 professionalsummary +cv-modern_professional 0:6fbdc8b79878 -0.07 0.10 platformengineerwith10+yearsbuil +cv-modern_professional 0:5f94c50dc5bf 0.36 0.10 technicalskills +cv-modern_professional 0:eea537278f83 0.23 0.10 •languages:java21,kotlin,groovy, +cv-modern_professional 0:9c2cd7231a53 0.23 0.10 •document&print:pdfbox,apachepoi +cv-modern_professional 0:7bf8639ec5d3 0.23 0.10 •layoutengines:customdsldesign,s +cv-modern_professional 0:8e66776d28d7 0.23 0.10 •build&infrastructure:maven,grad +cv-modern_professional 0:1ed4fc7d7768 0.23 0.10 •testing:junit5,assertj,pdfbox-b +cv-modern_professional 0:26671c309eb9 0.23 0.10 •distribution:mavencentral,sonat +cv-modern_professional 0:68bf0109c6f8 0.37 0.10 education +cv-modern_professional 0:0ad1957d6bab 0.23 0.10 msccomputerscience +cv-modern_professional 0:3fa772117260 0.24 0.18 2019-2021 +cv-modern_professional 0:3fa772117260#1 0.25 0.18 2019-2021 +cv-modern_professional 0:47ce0218bbea 0.18 0.10 universityofmanchester +cv-modern_professional 0:2ffe115b06e5 0.24 0.10 distinction.thesis:composablelay +cv-modern_professional 0:b6749d0b616b 0.23 0.10 bscsoftwareengineering +cv-modern_professional 0:30f9262640a0 0.24 0.18 2015-2019 +cv-modern_professional 0:89ad9656f393 0.18 0.10 imperialcollegelondon +cv-modern_professional 0:baa173b4a82e 0.24 0.10 first-classhonours.specialisatio +cv-modern_professional 0:6d3d5673c39f 0.23 0.10 oraclejavacertification +cv-modern_professional 0:d40b22f00acb 0.24 0.18 2023-2024 +cv-modern_professional 0:2669e1f6d55c 0.18 0.10 professionaltrack +cv-modern_professional 0:3857373829c1 0.24 0.10 java17platformdeep-dive:records, +cv-modern_professional 0:2577c0f557b2 0.37 0.10 projects +cv-modern_professional 0:b2b029995203 0.24 0.10 •graphcompose(java21,pdfbox,mave +cv-modern_professional 0:dd39d2ff3520 -0.06 0.10 declarativejavapdflayoutengine.s +cv-modern_professional 0:9ecaa6df6d41 -0.06 0.10 invoice/proposalpipelinesforhiri +cv-modern_professional 0:1b50bb81df5a 0.24 0.10 •templatestudio(kotlin,composede +cv-modern_professional 0:18eec9e76e2d -0.06 0.10 internaltoolforevaluatingcv,prop +cv-modern_professional 0:6bc2807453c6 -0.06 0.10 baselinefreezing. +cv-modern_professional 0:25cdca2beb8b 0.24 0.10 •layoutlint(java21,javaparser,sp +cv-modern_professional 0:cc2850ddd8ba -0.06 0.10 staticanalyserthatflagsfragileau +cv-modern_professional 0:7b985a1d2b08 -0.06 0.10 shiptoproduction. +cv-modern_professional 0:fb1927f88597 0.24 0.10 •chromeforge(java,graphcompose,p +cv-modern_professional 0:cda7db6c6ea6 -0.06 0.10 editorial-magazinedocumenttoolki +cv-modern_professional 0:fe63fe18585a -0.06 0.10 callouts. +cv-modern_professional 0:c2f296ef30a3 0.38 0.10 professionalexperience +cv-modern_professional 0:a76f47480818 0.24 0.10 seniorplatformengineer +cv-modern_professional 0:060300b18051 0.25 0.15 2024-present +cv-modern_professional 0:f890faef907f 0.19 0.10 northwindsystems +cv-modern_professional 0:a6525dacbac7 -0.05 0.10 ledthereusabledocument-generatio +cv-modern_professional 0:15e3905f4890 -0.05 0.10 reducedtemplatemaintenancetimeby +cv-modern_professional 0:daf65306b3b6 0.24 0.10 softwareengineer +cv-modern_professional 0:e7cc1822c6dc 0.25 0.18 2021-2024 +cv-modern_professional 0:998c1a985022 0.19 0.10 brightleaflabs +cv-modern_professional 0:e86691b0219f -0.05 0.10 builtbackendservicesandproductio +cv-modern_professional 0:4ec57434564a -0.05 0.10 migrationfromitexttoacustomlayou +cv-modern_professional 0:41bb54fbae8d 0.24 0.10 backendengineer +cv-modern_professional 0:ef148f221e31 0.19 0.10 helixprintco +cv-modern_professional 0:a32c7f2401d9 -0.05 0.10 maintainedahigh-volumeinvoice-pr +cv-modern_professional 0:7068c1d7034b -0.05 0.10 everytemplatechange. cv-modern_professional 1:676dfdd56ad2 0.36 0.10 additionalinformation cv-modern_professional 1:f20997652453 0.23 0.10 languages:english(fluent),german cv-modern_professional 1:ec9d3622395e 0.23 0.10 workeligibility:eligibletoworkin @@ -951,32 +951,32 @@ cv-nordic_clean 0:c0b0109d9439 -0.12 -0.16 github cv-nordic_clean 0:1900eab6c028 -0.25 11.60 profile cv-nordic_clean 0:8d6758a29c08 -0.42 11.60 platformengineerwith10+yearsbuil cv-nordic_clean 0:f0d993eb5f9d -0.44 11.60 high-throughputpdfrendering,sema -cv-nordic_clean 0:32c1cf49a2fe -0.11 0.10 skills -cv-nordic_clean 0:873a24d153c8 0.01 0.10 languages:java21,kotlin,groovy,p -cv-nordic_clean 0:db84150190bb -0.17 0.10 document&print:pdfbox,apachepoi -cv-nordic_clean 0:1d1d129512e6 -0.15 0.10 (docx/xlsx),itext,postscript,icc -cv-nordic_clean 0:7985eee03934 -0.13 0.10 fontmetrics -cv-nordic_clean 0:a1cec3782701 -0.11 0.10 layoutengines:customdsldesign,se -cv-nordic_clean 0:3a3b8c3bddd0 -0.09 0.10 trees,pagination,snapshottesting -cv-nordic_clean 0:b7d8ca9428a4 -0.07 0.10 build&infrastructure:maven,gradl -cv-nordic_clean 0:656a2a3e57e0 -0.05 0.10 jitpack,docker,jmhbenchmarking -cv-nordic_clean 0:b8b1a42a45e1 -0.03 0.10 testing:junit5,assertj,pdfbox-ba -cv-nordic_clean 0:2ec2836b6df6 -0.01 0.10 layout-graphsnapshots,mutationte -cv-nordic_clean 0:74b69eb8de4b 0.01 0.10 distribution:mavencentral,sonaty -cv-nordic_clean 0:43ad67a4e3f5 0.03 0.10 signing,jitpack,semanticversioni -cv-nordic_clean 0:68bf0109c6f8 0.11 0.10 education -cv-nordic_clean 0:904a600c3869 0.03 0.10 msccomputerscience/universityofm -cv-nordic_clean 0:3fa772117260 0.22 0.10 2019-2021 -cv-nordic_clean 0:78a380e4d1f0 0.25 0.10 bscsoftwareengineering/imperialc -cv-nordic_clean 0:30f9262640a0 0.44 0.10 2015-2019 -cv-nordic_clean 0:7b476727faf3 0.75 0.10 additional -cv-nordic_clean 0:3b0f5db9217f 0.62 0.10 languages:english(fluent),german -cv-nordic_clean 0:d8a971cea795 0.60 0.10 spanish(basic) -cv-nordic_clean 0:ec9d3622395e 0.83 0.10 workeligibility:eligibletoworkin -cv-nordic_clean 0:d05b8b335e96 0.56 0.10 opensource:maintainerofgraphcomp -cv-nordic_clean 0:2f3b4176123d 0.54 0.10 contributortopdfboxissuetriage. -cv-nordic_clean 0:b6b5a250cb72 0.52 0.10 speaking:jvmsummit2024,devoxxuk2 -cv-nordic_clean 0:7ead14c50085 0.50 0.10 ondeclarativedocumentlayout. +cv-nordic_clean 0:32c1cf49a2fe -0.31 0.10 skills +cv-nordic_clean 0:873a24d153c8 -0.19 0.10 languages:java21,kotlin,groovy,p +cv-nordic_clean 0:db84150190bb -0.37 0.10 document&print:pdfbox,apachepoi +cv-nordic_clean 0:1d1d129512e6 -0.35 0.10 (docx/xlsx),itext,postscript,icc +cv-nordic_clean 0:7985eee03934 -0.33 0.10 fontmetrics +cv-nordic_clean 0:a1cec3782701 -0.31 0.10 layoutengines:customdsldesign,se +cv-nordic_clean 0:3a3b8c3bddd0 -0.29 0.10 trees,pagination,snapshottesting +cv-nordic_clean 0:b7d8ca9428a4 -0.27 0.10 build&infrastructure:maven,gradl +cv-nordic_clean 0:656a2a3e57e0 -0.25 0.10 jitpack,docker,jmhbenchmarking +cv-nordic_clean 0:b8b1a42a45e1 -0.23 0.10 testing:junit5,assertj,pdfbox-ba +cv-nordic_clean 0:2ec2836b6df6 -0.21 0.10 layout-graphsnapshots,mutationte +cv-nordic_clean 0:74b69eb8de4b -0.19 0.10 distribution:mavencentral,sonaty +cv-nordic_clean 0:43ad67a4e3f5 -0.17 0.10 signing,jitpack,semanticversioni +cv-nordic_clean 0:68bf0109c6f8 -0.09 0.10 education +cv-nordic_clean 0:904a600c3869 -0.17 0.10 msccomputerscience/universityofm +cv-nordic_clean 0:3fa772117260 0.02 0.10 2019-2021 +cv-nordic_clean 0:78a380e4d1f0 0.05 0.10 bscsoftwareengineering/imperialc +cv-nordic_clean 0:30f9262640a0 0.24 0.10 2015-2019 +cv-nordic_clean 0:7b476727faf3 0.55 0.10 additional +cv-nordic_clean 0:3b0f5db9217f 0.42 0.10 languages:english(fluent),german +cv-nordic_clean 0:d8a971cea795 0.40 0.10 spanish(basic) +cv-nordic_clean 0:ec9d3622395e 0.63 0.10 workeligibility:eligibletoworkin +cv-nordic_clean 0:d05b8b335e96 0.36 0.10 opensource:maintainerofgraphcomp +cv-nordic_clean 0:2f3b4176123d 0.34 0.10 contributortopdfboxissuetriage. +cv-nordic_clean 0:b6b5a250cb72 0.32 0.10 speaking:jvmsummit2024,devoxxuk2 +cv-nordic_clean 0:7ead14c50085 0.30 0.10 ondeclarativedocumentlayout. cv-nordic_clean 0:53e5e7c5a884 -0.31 0.11 experience cv-nordic_clean 0:4977534824cc -0.23 0.11 seniorplatformengineer/2024-pres cv-nordic_clean 0:f890faef907f -0.19 0.11 northwindsystems @@ -1105,80 +1105,80 @@ cv-orange_ops 0:0945b35c95a8 0.84 0.02 systems:sapewm,manhattanwms,micr cv-orange_ops 0:44aaa523dc2c 0.84 0.02 languages:english(native) cv-orange_ops 0:724cc536a24c 0.85 0.02 drivinglicence:fullukdrivinglice cv-orange_ops 0:9f0e43069d3f 0.86 0.02 interests:strengthtraining,motor -cv-panel 0:8f1010120ed6 -0.40 8.57 jordanrivera -cv-panel 0:2d58f0cadc2d 0.12 8.27 platformengineer -cv-panel 0:89ff05847e96 0.19 8.54 london,uk|+442055551000 -cv-panel 0:8817bf9310b6 0.21 8.55 jordan.rivera@example.com|linked -cv-panel 0:1900eab6c028 0.19 8.35 profile -cv-panel 0:80cc87fdc4c4 -0.23 8.35 platformengineerwith10+yearsbuil -cv-panel 0:c323ef4c385f -0.21 8.35 systems.specialisedinhigh-throug -cv-panel 0:3ff1933dba9a -0.19 8.35 typed,snapshot-testedlibrariesth -cv-panel 0:32c1cf49a2fe 0.49 0.15 skills -cv-panel 0:eea537278f83 0.27 0.15 •languages:java21,kotlin,groovy, -cv-panel 0:7e941e729572 0.09 0.15 •document&print:pdfbox,apachepoi -cv-panel 0:9e3166ce2413 0.11 0.15 itext,postscript,icccolourprofil -cv-panel 0:ebc70ed9b71b 0.13 0.15 •layoutengines:customdsldesign,s -cv-panel 0:dd4f24d85605 0.15 0.15 pagination,snapshottesting,visua -cv-panel 0:f5f76d479ec8 0.17 0.15 •build&infrastructure:maven,grad -cv-panel 0:656a2a3e57e0 0.19 0.15 jitpack,docker,jmhbenchmarking -cv-panel 0:9a6921f79b7d 0.25 0.15 •distribution:mavencentral,sonat -cv-panel 0:77a74982066f 0.27 0.15 jitpack,semanticversioningdiscip -cv-panel 0:68bf0109c6f8 0.50 0.15 education -cv-panel 0:871923f4f0f2 0.28 0.15 msccomputerscience-2019-2021 -cv-panel 0:47ce0218bbea 0.30 0.15 universityofmanchester -cv-panel 0:51e1ec7daa5a 0.10 0.15 distinction.thesis:composablelay -cv-panel 0:d10553cd7368 0.12 0.15 deterministicdocumentrendering. -cv-panel 0:ba6d361079f4 0.34 0.15 bscsoftwareengineering-2015-2019 -cv-panel 0:89ad9656f393 0.36 0.15 imperialcollegelondon -cv-panel 0:4c58bcad7242 0.16 0.15 first-classhonours.specialisatio -cv-panel 0:2189b9b3b549 0.18 0.15 analysis. -cv-panel 0:8971b01c36bb 0.40 0.15 oraclejavacertification-2023-202 -cv-panel 0:2669e1f6d55c 0.42 0.15 professionaltrack -cv-panel 0:4f17e3d7d6f4 0.22 0.15 java17platformdeep-dive:records, -cv-panel 0:9e6154a3b625 0.24 0.15 matching,virtualthreads. -cv-panel 0:7b476727faf3 0.47 0.15 additional -cv-panel 0:3f88eb4c530c 0.05 0.15 languages:english(fluent),german -cv-panel 0:5d276fee8c17 0.07 0.15 (basic) -cv-panel 0:ec9d3622395e 0.29 0.15 workeligibility:eligibletoworkin -cv-panel 0:d05b8b335e96 0.11 0.15 opensource:maintainerofgraphcomp -cv-panel 0:2f3b4176123d 0.13 0.15 contributortopdfboxissuetriage. -cv-panel 0:1ae173b42166 0.15 0.15 speaking:jvmsummit2024,devoxxuk2 -cv-panel 0:309255ca6a36 0.17 0.15 declarativedocumentlayout. -cv-panel 0:53e5e7c5a884 0.49 0.16 experience -cv-panel 0:99b44abc1b3e 0.27 0.16 seniorplatformengineer-2024-pres -cv-panel 0:f890faef907f 0.29 0.16 northwindsystems -cv-panel 0:e32ca827bfd5 0.09 0.16 ledthereusabledocument-generatio -cv-panel 0:675f8862fdda 0.11 0.16 hiring,andreportingflowsacross8p -cv-panel 0:93d48fc85054 0.13 0.16 templatemaintenancetimeby70%byre -cv-panel 0:e7f09e2ba7d2 0.15 0.16 scriptsinfavourofonecanonicaleng -cv-panel 0:ded138c59d03 0.37 0.16 softwareengineer-2021-2024 -cv-panel 0:998c1a985022 0.39 0.16 brightleaflabs -cv-panel 0:0ed66ac9265d 0.19 0.16 builtbackendservicesandproductio -cv-panel 0:17c4ef49d4e6 0.21 0.16 pipelinesprocessing2m+documentsp -cv-panel 0:a7dd3c5be76b 0.23 0.16 migrationfromitexttoacustomlayou -cv-panel 0:a35401d8bcad 0.25 0.16 licensingriskandcuttingp99render -cv-panel 0:649d2d9d10d0 0.27 0.16 380ms. -cv-panel 0:019bbdc8d0bb 0.49 0.16 backendengineer-2019-2021 -cv-panel 0:ef148f221e31 0.51 0.16 helixprintco -cv-panel 0:09cc06a649eb 0.31 0.16 maintainedahigh-volumeinvoice-pr -cv-panel 0:090e2184c17b 0.33 0.16 pdfs/year)andauthoredthecomplian -cv-panel 0:6f071fdf7529 0.35 0.16 gatedeverytemplatechange. -cv-panel 0:2577c0f557b2 0.58 0.16 projects -cv-panel 0:b2b029995203 0.36 0.16 •graphcompose(java21,pdfbox,mave -cv-panel 0:81c8132f9792 0.24 0.16 systems.(opensource) -cv-panel 0:753f46e4e01b 0.26 0.16 •templatestudio(kotlin,composede -cv-panel 0:6eb35b5b9a91 0.28 0.16 diff) -cv-panel 0:d919bd2d50b6 0.30 0.16 internaltoolforevaluatingcv,prop -cv-panel 0:245b9e56b9de 0.32 0.16 across14designpresets.pngdiffing -cv-panel 0:6bc2807453c6 0.34 0.16 baselinefreezing. -cv-panel 0:25cdca2beb8b 0.56 0.16 •layoutlint(java21,javaparser,sp -cv-panel 0:30e034b9c7b2 0.38 0.16 staticanalyserthatflagsfragileau -cv-panel 0:e7ad19d64668 0.40 0.16 nestedrows,untypedoffsets,implic -cv-panel 0:95ac1a62c76f 0.42 0.16 theyshiptoproduction. -cv-panel 0:fb1927f88597 0.64 0.16 •chromeforge(java,graphcompose,p -cv-panel 0:bb865a4ccac1 0.46 0.16 editorial-magazinedocumenttoolki -cv-panel 0:8a31ccd889ee 0.48 0.16 cinematiccovers,pullquotes,multi -cv-panel 0:fe63fe18585a 0.50 0.16 callouts. +cv-panel 0:8f1010120ed6 -0.65 8.57 jordanrivera +cv-panel 0:2d58f0cadc2d -0.13 8.27 platformengineer +cv-panel 0:89ff05847e96 -0.06 8.54 london,uk|+442055551000 +cv-panel 0:8817bf9310b6 -0.04 8.55 jordan.rivera@example.com|linked +cv-panel 0:1900eab6c028 0.39 8.35 profile +cv-panel 0:80cc87fdc4c4 -0.03 8.35 platformengineerwith10+yearsbuil +cv-panel 0:c323ef4c385f -0.01 8.35 systems.specialisedinhigh-throug +cv-panel 0:3ff1933dba9a 0.01 8.35 typed,snapshot-testedlibrariesth +cv-panel 0:32c1cf49a2fe 0.69 0.15 skills +cv-panel 0:eea537278f83 0.47 0.15 •languages:java21,kotlin,groovy, +cv-panel 0:7e941e729572 0.29 0.15 •document&print:pdfbox,apachepoi +cv-panel 0:9e3166ce2413 0.31 0.15 itext,postscript,icccolourprofil +cv-panel 0:ebc70ed9b71b 0.33 0.15 •layoutengines:customdsldesign,s +cv-panel 0:dd4f24d85605 0.35 0.15 pagination,snapshottesting,visua +cv-panel 0:f5f76d479ec8 0.37 0.15 •build&infrastructure:maven,grad +cv-panel 0:656a2a3e57e0 0.39 0.15 jitpack,docker,jmhbenchmarking +cv-panel 0:9a6921f79b7d 0.45 0.15 •distribution:mavencentral,sonat +cv-panel 0:77a74982066f 0.47 0.15 jitpack,semanticversioningdiscip +cv-panel 0:68bf0109c6f8 1.15 0.15 education +cv-panel 0:871923f4f0f2 0.93 0.15 msccomputerscience-2019-2021 +cv-panel 0:47ce0218bbea 0.95 0.15 universityofmanchester +cv-panel 0:51e1ec7daa5a 0.75 0.15 distinction.thesis:composablelay +cv-panel 0:d10553cd7368 0.77 0.15 deterministicdocumentrendering. +cv-panel 0:ba6d361079f4 0.99 0.15 bscsoftwareengineering-2015-2019 +cv-panel 0:89ad9656f393 1.01 0.15 imperialcollegelondon +cv-panel 0:4c58bcad7242 0.81 0.15 first-classhonours.specialisatio +cv-panel 0:2189b9b3b549 0.83 0.15 analysis. +cv-panel 0:8971b01c36bb 1.05 0.15 oraclejavacertification-2023-202 +cv-panel 0:2669e1f6d55c 1.07 0.15 professionaltrack +cv-panel 0:4f17e3d7d6f4 0.87 0.15 java17platformdeep-dive:records, +cv-panel 0:9e6154a3b625 0.89 0.15 matching,virtualthreads. +cv-panel 0:7b476727faf3 1.57 0.15 additional +cv-panel 0:3f88eb4c530c 1.15 0.15 languages:english(fluent),german +cv-panel 0:5d276fee8c17 1.17 0.15 (basic) +cv-panel 0:ec9d3622395e 1.39 0.15 workeligibility:eligibletoworkin +cv-panel 0:d05b8b335e96 1.21 0.15 opensource:maintainerofgraphcomp +cv-panel 0:2f3b4176123d 1.23 0.15 contributortopdfboxissuetriage. +cv-panel 0:1ae173b42166 1.25 0.15 speaking:jvmsummit2024,devoxxuk2 +cv-panel 0:309255ca6a36 1.27 0.15 declarativedocumentlayout. +cv-panel 0:53e5e7c5a884 0.69 0.16 experience +cv-panel 0:99b44abc1b3e 0.47 0.16 seniorplatformengineer-2024-pres +cv-panel 0:f890faef907f 0.49 0.16 northwindsystems +cv-panel 0:e32ca827bfd5 0.29 0.16 ledthereusabledocument-generatio +cv-panel 0:675f8862fdda 0.31 0.16 hiring,andreportingflowsacross8p +cv-panel 0:93d48fc85054 0.33 0.16 templatemaintenancetimeby70%byre +cv-panel 0:e7f09e2ba7d2 0.35 0.16 scriptsinfavourofonecanonicaleng +cv-panel 0:ded138c59d03 0.57 0.16 softwareengineer-2021-2024 +cv-panel 0:998c1a985022 0.59 0.16 brightleaflabs +cv-panel 0:0ed66ac9265d 0.39 0.16 builtbackendservicesandproductio +cv-panel 0:17c4ef49d4e6 0.41 0.16 pipelinesprocessing2m+documentsp +cv-panel 0:a7dd3c5be76b 0.43 0.16 migrationfromitexttoacustomlayou +cv-panel 0:a35401d8bcad 0.45 0.16 licensingriskandcuttingp99render +cv-panel 0:649d2d9d10d0 0.47 0.16 380ms. +cv-panel 0:019bbdc8d0bb 0.69 0.16 backendengineer-2019-2021 +cv-panel 0:ef148f221e31 0.71 0.16 helixprintco +cv-panel 0:09cc06a649eb 0.51 0.16 maintainedahigh-volumeinvoice-pr +cv-panel 0:090e2184c17b 0.53 0.16 pdfs/year)andauthoredthecomplian +cv-panel 0:6f071fdf7529 0.55 0.16 gatedeverytemplatechange. +cv-panel 0:2577c0f557b2 1.23 0.16 projects +cv-panel 0:b2b029995203 1.01 0.16 •graphcompose(java21,pdfbox,mave +cv-panel 0:81c8132f9792 0.89 0.16 systems.(opensource) +cv-panel 0:753f46e4e01b 0.91 0.16 •templatestudio(kotlin,composede +cv-panel 0:6eb35b5b9a91 0.93 0.16 diff) +cv-panel 0:d919bd2d50b6 0.95 0.16 internaltoolforevaluatingcv,prop +cv-panel 0:245b9e56b9de 0.97 0.16 across14designpresets.pngdiffing +cv-panel 0:6bc2807453c6 0.99 0.16 baselinefreezing. +cv-panel 0:25cdca2beb8b 1.21 0.16 •layoutlint(java21,javaparser,sp +cv-panel 0:30e034b9c7b2 1.03 0.16 staticanalyserthatflagsfragileau +cv-panel 0:e7ad19d64668 1.05 0.16 nestedrows,untypedoffsets,implic +cv-panel 0:95ac1a62c76f 1.07 0.16 theyshiptoproduction. +cv-panel 0:fb1927f88597 1.29 0.16 •chromeforge(java,graphcompose,p +cv-panel 0:bb865a4ccac1 1.11 0.16 editorial-magazinedocumenttoolki +cv-panel 0:8a31ccd889ee 1.13 0.16 cinematiccovers,pullquotes,multi +cv-panel 0:fe63fe18585a 1.15 0.16 callouts. cv-professional_sidebar 0:093e7d5fdbaa -0.23 0.10 contact cv-professional_sidebar 0:7f459725e1f6 -0.03 0.00 +12345678900 cv-professional_sidebar 0:52bf11c1afe0 -0.08 0.00 your.email@example.com @@ -1276,17 +1276,17 @@ cv-serif_headline 0:2198cdea3aba 0.44 0.10 devsphere|newyork,ny cv-serif_headline 0:173ed9f7b6b1 0.45 0.10 •assistedindevelopingandmaintain cv-serif_headline 0:0a1fbe0c94d9 0.45 0.10 •wroteunitandintegrationteststoe cv-serif_headline 0:bd5eec545fa8 0.46 0.10 •participatedinagileceremoniesan -cv-serif_headline 0:2577c0f557b2 0.54 0.13 projects -cv-serif_headline 0:c03ade0f8985 0.59 0.13 e-commerceplatform -cv-serif_headline 0:f726495cb8e6 0.59 0.13 java,springboot,react,postgresql -cv-serif_headline 0:09271909c2c5 0.36 0.13 developedafull-stacke-commerce -cv-serif_headline 0:a395647dca6c 0.36 0.13 platformwithuserauthentication,p -cv-serif_headline 0:19ed6c29c718 0.36 0.13 catalog,cart,andpaymentintegrati -cv-serif_headline 0:1c1e5cfc5031 0.59 0.11 taskmanagementapi -cv-serif_headline 0:4e8f2a166cfe 0.59 0.11 java,springboot,mongodb,docker -cv-serif_headline 0:793437bcb507 0.36 0.11 builtarestfulapifortaskmanagemen -cv-serif_headline 0:47492456be77 0.36 0.11 withrole-basedaccess,real-time -cv-serif_headline 0:7d9a1a98ac6c 0.36 0.11 updates,anddockerizeddeployment. +cv-serif_headline 0:2577c0f557b2 0.44 0.13 projects +cv-serif_headline 0:c03ade0f8985 0.49 0.13 e-commerceplatform +cv-serif_headline 0:f726495cb8e6 0.49 0.13 java,springboot,react,postgresql +cv-serif_headline 0:09271909c2c5 0.26 0.13 developedafull-stacke-commerce +cv-serif_headline 0:a395647dca6c 0.26 0.13 platformwithuserauthentication,p +cv-serif_headline 0:19ed6c29c718 0.26 0.13 catalog,cart,andpaymentintegrati +cv-serif_headline 0:1c1e5cfc5031 0.49 0.11 taskmanagementapi +cv-serif_headline 0:4e8f2a166cfe 0.49 0.11 java,springboot,mongodb,docker +cv-serif_headline 0:793437bcb507 0.26 0.11 builtarestfulapifortaskmanagemen +cv-serif_headline 0:47492456be77 0.26 0.11 withrole-basedaccess,real-time +cv-serif_headline 0:7d9a1a98ac6c 0.26 0.11 updates,anddockerizeddeployment. cv-serif_headline 0:68bf0109c6f8 0.00 0.09 education cv-serif_headline 0:6a75b3a10877 0.07 0.14 m.s.incomputerscience cv-serif_headline 0:d244381bfb58 0.10 0.14 newyorkuniversity @@ -1685,6 +1685,7 @@ cv-timeline_minimal 0:54b7bb3a12a0 -0.45 0.10 jmh):declarativejavapdflayouteng cv-timeline_minimal 0:83ee0a75c2d4 -0.45 0.10 semanticdsl,slot-basedtemplates, cv-timeline_minimal 0:235802baf524 -0.45 0.10 snapshottesting.powersproduction cv-timeline_minimal 0:44925c9e42ee -0.45 0.10 invoice/proposalpipelinesforhiri +cv-timeline_minimal 0:de1af4623873 -0.45 0.10 andbillingsystems.(opensource) cv-timeline_minimal 0:ae7902eee4b2 -0.45 0.10 templatestudio(kotlin,composedes cv-timeline_minimal 0:f15436034237 -0.45 0.10 pdfboxpngdiff):internaltoolfor cv-timeline_minimal 0:24a195694090 -0.45 0.10 evaluatingcv,proposal,andinvoice @@ -1761,49 +1762,49 @@ cv-violet_grid 0:caf9f906b16a -0.22 -0.45 documentation cv-violet_grid 0:f9d35d43770d -0.24 0.10 tools cv-violet_grid 0:5cb2b3b6143c -0.18 0.10 figmafigjamadobexdsketchmironoti cv-violet_grid 0:53e5e7c5a884 -0.20 0.10 experience -cv-violet_grid 0:5a0774260e0c -0.08 0.10 2022-present -cv-violet_grid 0:204f460767ff -0.12 0.02 seniorux/uidesigner|novafin(fint -cv-violet_grid 0:318bba211bdc -0.07 -0.28 sanfrancisco,ca -cv-violet_grid 0:318bba211bdc#1 -0.15 -0.28 sanfrancisco,ca -cv-violet_grid 0:3883e88c63c3 -0.08 0.05 ledend-to-enddesignforapersonalf -cv-violet_grid 0:ccc00663f089 -0.10 0.05 conducteduserresearch,builtperso -cv-violet_grid 0:7d0f908c7e5f -0.12 0.05 designedwireframes,prototypes,an -cv-violet_grid 0:9b57c4a85aad -0.13 0.05 establishedandmaintainedascalabl -cv-violet_grid 0:6894eafb99c2 -0.15 0.05 collaboratedwithproductmanagers, -cv-violet_grid 0:01e4455cec51 -0.16 0.10 2020-2022 -cv-violet_grid 0:24d722f0cfbe -0.20 0.02 uxdesigner|brighthealth(healthte -cv-violet_grid 0:530707fb0897 -0.16 0.05 redesignedpatientportalexperienc -cv-violet_grid 0:b2e27a1d9270 -0.18 0.05 plannedandfacilitatedusabilityte -cv-violet_grid 0:ab80a52d70fe -0.20 0.05 partneredwithengineerstoensurefe -cv-violet_grid 0:11cbf615189b -0.21 0.05 createdreusablecomponentsandstyl -cv-violet_grid 0:7e5081a3ed48 -0.22 0.10 2018-2020 -cv-violet_grid 0:73f7bbf7cd60 -0.26 0.02 juniorux/uidesigner|lumendigital -cv-violet_grid 0:c6b06045332f -0.21 -0.17 austin,tx -cv-violet_grid 0:5ea8234925c5 -0.22 0.05 supporteddiscoveryworkshops,user -cv-violet_grid 0:46f00c76528c -0.24 0.05 designedresponsivewebsitesandlan -cv-violet_grid 0:f3cea36a9d83 -0.26 0.05 collaboratedwithcopywritersandde -cv-violet_grid 0:d94eccbb1fbe -0.29 0.10 selectedprojects -cv-violet_grid 0:45dc8bf81211 -0.34 0.08 novafinmobileapp|personalfinance -cv-violet_grid 0:d398b29d3dbb -0.29 0.61 2023 -cv-violet_grid 0:e66c1ce573d3 -0.43 0.08 ledux/uidesignforbudgeting,goalt -cv-violet_grid 0:0ed8829e68d0 -0.43 0.08 thatinformedasimplifiednavigatio -cv-violet_grid 0:ee9bd17ebccf -0.43 0.08 22%increaseinweeklyactiveusers. -cv-violet_grid 0:28b4603d784a -0.35 0.08 brighthealthpatientportal|health -cv-violet_grid 0:1bea20e1df19 -0.30 0.61 2021 -cv-violet_grid 0:999ddb26bed6 -0.44 0.08 redesignedkeypatientflowsincludi -cv-violet_grid 0:073d15633c0b -0.44 0.08 systemandcomponentlibraryusedacr -cv-violet_grid 0:68bf0109c6f8 -0.19 0.10 education -cv-violet_grid 0:6cb574fa10b6 -0.19 0.07 languages -cv-violet_grid 0:0cf7506cf94a -0.12 0.10 bacheloroffineartsingraphicdesig -cv-violet_grid 0:00ab7a6aa5f1 -0.11 0.10 californiacollegeofthearts -cv-violet_grid 0:7e2c21bb41db -0.12 0.10 sanfrancisco,ca|2014-2018 -cv-violet_grid 0:b6234d2ea0d6 -1.47 0.02 english -cv-violet_grid 0:bef32d2c315a -1.48 -0.03 native -cv-violet_grid 0:bef32d2c315a#1 -1.44 -0.03 native -cv-violet_grid 0:9c9b13446cd9 -1.44 0.02 spanish -cv-violet_grid 0:e35242c809c8 -1.41 0.02 portuguese -cv-violet_grid 0:c5d1de4964d6 -1.41 -0.03 conversational -cv-violet_grid 0:1de4fede4f63 -1.16 22.41 idesignwithempathy,iteratewithpu +cv-violet_grid 0:5a0774260e0c -0.18 0.10 2022-present +cv-violet_grid 0:204f460767ff -0.22 0.02 seniorux/uidesigner|novafin(fint +cv-violet_grid 0:318bba211bdc -0.17 -0.28 sanfrancisco,ca +cv-violet_grid 0:318bba211bdc#1 -0.25 -0.28 sanfrancisco,ca +cv-violet_grid 0:3883e88c63c3 -0.18 0.05 ledend-to-enddesignforapersonalf +cv-violet_grid 0:ccc00663f089 -0.20 0.05 conducteduserresearch,builtperso +cv-violet_grid 0:7d0f908c7e5f -0.22 0.05 designedwireframes,prototypes,an +cv-violet_grid 0:9b57c4a85aad -0.23 0.05 establishedandmaintainedascalabl +cv-violet_grid 0:6894eafb99c2 -0.25 0.05 collaboratedwithproductmanagers, +cv-violet_grid 0:01e4455cec51 -0.26 0.10 2020-2022 +cv-violet_grid 0:24d722f0cfbe -0.30 0.02 uxdesigner|brighthealth(healthte +cv-violet_grid 0:530707fb0897 -0.26 0.05 redesignedpatientportalexperienc +cv-violet_grid 0:b2e27a1d9270 -0.28 0.05 plannedandfacilitatedusabilityte +cv-violet_grid 0:ab80a52d70fe -0.30 0.05 partneredwithengineerstoensurefe +cv-violet_grid 0:11cbf615189b -0.31 0.05 createdreusablecomponentsandstyl +cv-violet_grid 0:7e5081a3ed48 -0.32 0.10 2018-2020 +cv-violet_grid 0:73f7bbf7cd60 -0.36 0.02 juniorux/uidesigner|lumendigital +cv-violet_grid 0:c6b06045332f -0.31 -0.17 austin,tx +cv-violet_grid 0:5ea8234925c5 -0.32 0.05 supporteddiscoveryworkshops,user +cv-violet_grid 0:46f00c76528c -0.34 0.05 designedresponsivewebsitesandlan +cv-violet_grid 0:f3cea36a9d83 -0.36 0.05 collaboratedwithcopywritersandde +cv-violet_grid 0:d94eccbb1fbe -0.39 0.10 selectedprojects +cv-violet_grid 0:45dc8bf81211 -0.44 0.08 novafinmobileapp|personalfinance +cv-violet_grid 0:d398b29d3dbb -0.39 0.61 2023 +cv-violet_grid 0:e66c1ce573d3 -0.53 0.08 ledux/uidesignforbudgeting,goalt +cv-violet_grid 0:0ed8829e68d0 -0.53 0.08 thatinformedasimplifiednavigatio +cv-violet_grid 0:ee9bd17ebccf -0.53 0.08 22%increaseinweeklyactiveusers. +cv-violet_grid 0:28b4603d784a -0.45 0.08 brighthealthpatientportal|health +cv-violet_grid 0:1bea20e1df19 -0.40 0.61 2021 +cv-violet_grid 0:999ddb26bed6 -0.54 0.08 redesignedkeypatientflowsincludi +cv-violet_grid 0:073d15633c0b -0.54 0.08 systemandcomponentlibraryusedacr +cv-violet_grid 0:68bf0109c6f8 -0.29 0.10 education +cv-violet_grid 0:6cb574fa10b6 -0.29 0.07 languages +cv-violet_grid 0:0cf7506cf94a -0.22 0.10 bacheloroffineartsingraphicdesig +cv-violet_grid 0:00ab7a6aa5f1 -0.21 0.10 californiacollegeofthearts +cv-violet_grid 0:7e2c21bb41db -0.22 0.10 sanfrancisco,ca|2014-2018 +cv-violet_grid 0:b6234d2ea0d6 -1.57 0.02 english +cv-violet_grid 0:bef32d2c315a -1.58 -0.03 native +cv-violet_grid 0:bef32d2c315a#1 -1.54 -0.03 native +cv-violet_grid 0:9c9b13446cd9 -1.54 0.02 spanish +cv-violet_grid 0:e35242c809c8 -1.51 0.02 portuguese +cv-violet_grid 0:c5d1de4964d6 -1.51 -0.03 conversational +cv-violet_grid 0:1de4fede4f63 -1.26 22.41 idesignwithempathy,iteratewithpu invoice-classic 0:c26c22b94338 0.49 0.10 graphcomposestudio invoice-classic 0:c26c22b94338#1 0.25 0.06 graphcomposestudio invoice-classic 0:2a08ce5567fb 0.35 0.10 18layoutstreet @@ -2646,7 +2647,7 @@ invoice-luma_studio_long 2:bc6d215b63ee 0.01 1.04 page3of3 invoice-merchant 0:0dffa3b5d008 -0.01 0.10 coastline invoice-merchant 0:52d6e3de4fa0 0.08 0.85 invoice invoice-merchant 0:9422e2aeb800 0.08 0.08 coastlinecommerceinc. -invoice-merchant 0:9422e2aeb800#1 -1.80 0.53 coastlinecommerceinc. +invoice-merchant 0:9422e2aeb800#1 -1.90 0.53 coastlinecommerceinc. invoice-merchant 0:9422e2aeb800#2 -3.08 0.10 coastlinecommerceinc. invoice-merchant 0:8bb83c0c3efb 0.10 0.08 150elginstreet,8thfloor invoice-merchant 0:cf0df3462e70 0.09 0.08 ottawa,onk2p1l4 @@ -2654,12 +2655,12 @@ invoice-merchant 0:408c7c5887a0 0.09 0.08 canada invoice-merchant 0:0d9b94d29fc9 0.01 0.32 www.coastline.example invoice-merchant 0:0d9b94d29fc9#1 -3.08 0.10 www.coastline.example invoice-merchant 0:76957649b8a8 -0.02 0.32 billing@coastline.example -invoice-merchant 0:76957649b8a8#1 -1.77 0.53 billing@coastline.example +invoice-merchant 0:76957649b8a8#1 -1.87 0.53 billing@coastline.example invoice-merchant 0:0b44bf19dd44 -0.05 0.32 +1613-555-0142 invoice-merchant 0:884004f21362 -0.03 0.08 vatid:ca8139020285rt0001 invoice-merchant 0:6282391a4cc1 0.23 0.09 invoicenumber: invoice-merchant 0:a6e01b979f55 0.23 0.08 inv-2026-000789 -invoice-merchant 0:a6e01b979f55#1 -1.77 0.53 inv-2026-000789 +invoice-merchant 0:a6e01b979f55#1 -1.87 0.53 inv-2026-000789 invoice-merchant 0:8d05f5d55191 0.20 0.09 invoicedate: invoice-merchant 0:dc9696f61d36 0.20 0.08 27may2026 invoice-merchant 0:0e0fb0fc0939 0.18 0.09 duedate: @@ -2710,23 +2711,23 @@ invoice-merchant 0:0036ebf2cfb2 -1.87 0.07 prioritysupport invoice-merchant 0:6bfa3f8e9308 -1.92 0.07 24/7support invoice-merchant 0:7f0f70e643bc -1.91 -0.26 included invoice-merchant 0:3c7ade679fdf -1.92 0.51 paymentdetails -invoice-merchant 0:944d398aea60 -1.80 0.55 bankname: -invoice-merchant 0:d6c3cea2e943 -1.80 0.53 harbourbankofcanada -invoice-merchant 0:0ecb5847ffa7 -1.80 0.55 accountname: -invoice-merchant 0:6b4894c28363 -1.79 0.55 accountnumber: -invoice-merchant 0:ca2ea6319cc8 -1.79 0.53 1001-4267-153 -invoice-merchant 0:555043320c0c -1.79 0.55 swiftcode: -invoice-merchant 0:922f5f70c123 -1.79 0.53 hrbrcat2 -invoice-merchant 0:f1b1597830d6 -1.79 0.55 institutionnumber: -invoice-merchant 0:88c0413bfef1 -1.79 0.53 003 -invoice-merchant 0:e47c9313aced -1.78 0.55 transitnumber: -invoice-merchant 0:fec334e6bf8c -1.78 0.53 00016 -invoice-merchant 0:4f657c67e41a -1.78 0.55 accounttype: -invoice-merchant 0:b8b8acdf702e -1.78 0.53 cadaccount -invoice-merchant 0:fa0fbe194b51 -1.77 0.55 remittanceemail: -invoice-merchant 0:c608665436db -1.77 0.55 reference: -invoice-merchant 0:1b0fdc20ced4 -1.84 0.55 pleaseincludetheinvoicenumber -invoice-merchant 0:cfdf1faf410b -1.86 0.55 inyourpaymentreference. +invoice-merchant 0:944d398aea60 -1.90 0.55 bankname: +invoice-merchant 0:d6c3cea2e943 -1.90 0.53 harbourbankofcanada +invoice-merchant 0:0ecb5847ffa7 -1.90 0.55 accountname: +invoice-merchant 0:6b4894c28363 -1.89 0.55 accountnumber: +invoice-merchant 0:ca2ea6319cc8 -1.89 0.53 1001-4267-153 +invoice-merchant 0:555043320c0c -1.89 0.55 swiftcode: +invoice-merchant 0:922f5f70c123 -1.89 0.53 hrbrcat2 +invoice-merchant 0:f1b1597830d6 -1.89 0.55 institutionnumber: +invoice-merchant 0:88c0413bfef1 -1.89 0.53 003 +invoice-merchant 0:e47c9313aced -1.88 0.55 transitnumber: +invoice-merchant 0:fec334e6bf8c -1.88 0.53 00016 +invoice-merchant 0:4f657c67e41a -1.88 0.55 accounttype: +invoice-merchant 0:b8b8acdf702e -1.88 0.53 cadaccount +invoice-merchant 0:fa0fbe194b51 -1.87 0.55 remittanceemail: +invoice-merchant 0:c608665436db -1.87 0.55 reference: +invoice-merchant 0:1b0fdc20ced4 -1.94 0.55 pleaseincludetheinvoicenumber +invoice-merchant 0:cfdf1faf410b -1.96 0.55 inyourpaymentreference. invoice-merchant 0:d6577e95efba -1.91 0.10 subtotal invoice-merchant 0:30d16b02fd3e -1.84 0.88 444.00 invoice-merchant 0:2ee4d3de4ddf -1.89 0.10 tax(0%) @@ -2831,8 +2832,8 @@ invoice-metered 0:e50d8a0ea599 -9.60 0.70 gbp42.94 invoice-metered 0:57a66d21eb1b -9.73 0.14 totaldue invoice-metered 0:f207312dff2f -9.80 -0.05 gbp257.65 invoice-metered 0:b0553f008513 -9.64 0.11 paymentdueby -invoice-metered 0:e60e7ef06ccc -10.46 0.10 thankyouforrunningonnorthwindclo -invoice-metered 0:34ea2ec3fe72 -10.46 0.10 forbillingandaccountsupport,visi +invoice-metered 0:e60e7ef06ccc -9.51 0.10 thankyouforrunningonnorthwindclo +invoice-metered 0:34ea2ec3fe72 -9.51 0.10 forbillingandaccountsupport,visi invoice-metered 0:e28672d64882 -0.04 0.12 northwindcloudservicesltd.isasub invoice-metered 0:985e43c2de34 -0.04 0.12 120riversideway,bristol,bs16qt,u invoice-metered 0:7b14b8d2c5c4 -0.04 0.16 page1of1 @@ -3056,7 +3057,7 @@ invoice-obsidian 0:07f15cde5b18 0.14 0.09 kestrel invoice-obsidian 0:52d6e3de4fa0 0.12 0.09 invoice invoice-obsidian 0:5d1d1b79af09 0.02 0.09 invoicenumber invoice-obsidian 0:3e62d1fbe5ec 0.06 0.09 inv-2026-1048 -invoice-obsidian 0:3e62d1fbe5ec#1 -1.46 0.08 inv-2026-1048 +invoice-obsidian 0:3e62d1fbe5ec#1 -0.21 0.08 inv-2026-1048 invoice-obsidian 0:8feaf8016bab 0.02 0.09 issuedate invoice-obsidian 0:4d49cb78b810 0.02 0.11 27august2026 invoice-obsidian 0:ac10f8c16320 -0.05 0.09 duedate @@ -3067,76 +3068,76 @@ invoice-obsidian 0:466e5b9cd57f -0.19 0.09 currency invoice-obsidian 0:54f8e1b3fe44 -0.19 0.49 gbp invoice-obsidian 0:75857a458999 -0.26 0.10 from invoice-obsidian 0:7d7385ecfbd9 -0.29 0.07 kestrelbusiness -invoice-obsidian 0:7d7385ecfbd9#1 -1.43 0.08 kestrelbusiness -invoice-obsidian 0:7d7385ecfbd9#2 -1.12 -0.60 kestrelbusiness +invoice-obsidian 0:7d7385ecfbd9#1 -0.18 0.08 kestrelbusiness +invoice-obsidian 0:7d7385ecfbd9#2 -0.22 -0.60 kestrelbusiness invoice-obsidian 0:5f51304df361 -0.27 0.07 7harboursidewalk invoice-obsidian 0:895a6b59f677 -0.29 0.07 bristolbs15ty invoice-obsidian 0:2474519f77a9 -0.29 0.07 unitedkingdom invoice-obsidian 0:2474519f77a9#1 -0.29 0.08 unitedkingdom invoice-obsidian 0:70ec69d2102f -0.31 0.07 ar@kestrel.example -invoice-obsidian 0:70ec69d2102f#1 -1.12 -0.74 ar@kestrel.example +invoice-obsidian 0:70ec69d2102f#1 -0.22 -0.74 ar@kestrel.example invoice-obsidian 0:aeba3a7b3598 -0.26 0.11 billto invoice-obsidian 0:7bfc2b791f41 -0.29 0.08 northlineconsultingltd invoice-obsidian 0:13dd937d2fe6 -0.27 0.08 21jubileeway invoice-obsidian 0:f9bab6a0b45b -0.29 0.08 londonse13ss -invoice-obsidian 0:c9046f7a37ad -2.20 13.05 description -invoice-obsidian 0:32e8369a9c4f -2.20 12.90 qty -invoice-obsidian 0:d1062d072acd -2.20 12.40 unitprice -invoice-obsidian 0:a52611c9261b -2.20 12.30 vat(20%) -invoice-obsidian 0:a52611c9261b#1 -1.07 0.11 vat(20%) -invoice-obsidian 0:cf38d95c9c6b -2.20 12.52 amount -invoice-obsidian 0:15345cbad705 -1.42 13.05 subscriptionsetup -invoice-obsidian 0:5100476d46bb -1.42 13.05 one-offaccountandworkspacesetup -invoice-obsidian 0:507f9f133059 -1.46 12.48 £150.00 -invoice-obsidian 0:893d7480f763 -1.46 12.58 £30.00 -invoice-obsidian 0:893d7480f763#1 -4.18 12.59 £30.00 -invoice-obsidian 0:629184210581 -1.46 12.49 £180.00 -invoice-obsidian 0:3e8060178bc4 -2.06 13.05 internationalpaymentsupport -invoice-obsidian 0:33e4ab51097e -2.06 13.05 monthlysupportforcross-borderpay -invoice-obsidian 0:96d6b62c061d -2.10 12.48 £250.00 -invoice-obsidian 0:70d5b1312085 -2.10 12.58 £50.00 -invoice-obsidian 0:d86642b21e53 -2.10 12.49 £300.00 -invoice-obsidian 0:9399cf3b221a -2.71 13.05 expensemanagementintegration -invoice-obsidian 0:da2890c99f7a -2.71 13.05 apiaccessandintegration -invoice-obsidian 0:372ba7238228 -2.74 12.48 £200.00 -invoice-obsidian 0:05c6a4f7132f -2.74 12.58 £40.00 -invoice-obsidian 0:853580239989 -2.74 12.49 £240.00 -invoice-obsidian 0:ba80be228223 -3.35 13.05 virtualcards -invoice-obsidian 0:eae2564ef311 -3.35 13.05 50virtualcards -invoice-obsidian 0:cf02270203a4 -3.39 12.48 £100.00 -invoice-obsidian 0:33b5fc913817 -3.39 12.58 £20.00 -invoice-obsidian 0:8aec54fdb1a1 -3.39 12.49 £120.00 -invoice-obsidian 0:cc29e90932c5 -4.14 13.05 businessaccountmaintenance -invoice-obsidian 0:f1254de1a1d4 -4.14 13.05 monthlyaccountmaintenancefee -invoice-obsidian 0:8bf9ac7b27bd -4.18 12.68 £6.00 -invoice-obsidian 0:bff295cd3f97 -4.18 12.59 £36.00 -invoice-obsidian 0:d6577e95efba -1.04 0.11 subtotal -invoice-obsidian 0:4595e1b34cb1 -1.05 0.63 £730.00 -invoice-obsidian 0:eafa82a0eadf -1.09 0.63 £146.00 -invoice-obsidian 0:57a66d21eb1b -1.17 0.11 totaldue -invoice-obsidian 0:ad3ba615a506 -1.19 -0.59 £876.00 -invoice-obsidian 0:ab5aa97074c4 -1.38 0.08 notes -invoice-obsidian 0:0956d8d0441d -1.01 0.08 thankyouforchoosingkestrelbusine -invoice-obsidian 0:0b4d6f0e8783 -1.01 0.08 thisinvoicecoversservicesandfeat -invoice-obsidian 0:02e483554647 -1.00 0.08 toyourbusinessasofthedateofissue -invoice-obsidian 0:b439106fc5a1 -0.99 0.08 ifyouhaveanyquestionsaboutthisin -invoice-obsidian 0:877ac656a147 -0.98 0.08 pleasecontactusatar@kestrel.exam -invoice-obsidian 0:3c7ade679fdf -1.38 0.09 paymentdetails -invoice-obsidian 0:473fbeedb47c -1.90 0.11 pleasepaybybanktransfer -invoice-obsidian 0:59f2b74175d7 -1.89 0.11 totheaccountbelow. -invoice-obsidian 0:811f691f5582 -1.37 0.11 payee -invoice-obsidian 0:10aeacde20ff -1.38 0.11 sortcode -invoice-obsidian 0:a748c443f622 -1.44 0.08 04-00-75 -invoice-obsidian 0:f92a9c925024 -1.39 0.11 accountnumber -invoice-obsidian 0:ef797c8118f0 -1.45 0.08 12345678 -invoice-obsidian 0:52367a6622b1 -1.40 0.11 reference -invoice-obsidian 0:7c6ab37d83ef -1.12 0.08 thankyouforyourbusiness. -invoice-obsidian 0:a97667f07d1b -1.12 0.08 paymentisdueby10september2026. +invoice-obsidian 0:c9046f7a37ad -1.90 13.05 description +invoice-obsidian 0:32e8369a9c4f -1.90 12.90 qty +invoice-obsidian 0:d1062d072acd -1.90 12.40 unitprice +invoice-obsidian 0:a52611c9261b -1.90 12.30 vat(20%) +invoice-obsidian 0:a52611c9261b#1 -0.12 0.11 vat(20%) +invoice-obsidian 0:cf38d95c9c6b -1.90 12.52 amount +invoice-obsidian 0:15345cbad705 -1.12 13.05 subscriptionsetup +invoice-obsidian 0:5100476d46bb -1.12 13.05 one-offaccountandworkspacesetup +invoice-obsidian 0:507f9f133059 -1.16 12.48 £150.00 +invoice-obsidian 0:893d7480f763 -1.16 12.58 £30.00 +invoice-obsidian 0:893d7480f763#1 -3.88 12.59 £30.00 +invoice-obsidian 0:629184210581 -1.16 12.49 £180.00 +invoice-obsidian 0:3e8060178bc4 -1.76 13.05 internationalpaymentsupport +invoice-obsidian 0:33e4ab51097e -1.76 13.05 monthlysupportforcross-borderpay +invoice-obsidian 0:96d6b62c061d -1.80 12.48 £250.00 +invoice-obsidian 0:70d5b1312085 -1.80 12.58 £50.00 +invoice-obsidian 0:d86642b21e53 -1.80 12.49 £300.00 +invoice-obsidian 0:9399cf3b221a -2.41 13.05 expensemanagementintegration +invoice-obsidian 0:da2890c99f7a -2.41 13.05 apiaccessandintegration +invoice-obsidian 0:372ba7238228 -2.44 12.48 £200.00 +invoice-obsidian 0:05c6a4f7132f -2.44 12.58 £40.00 +invoice-obsidian 0:853580239989 -2.44 12.49 £240.00 +invoice-obsidian 0:ba80be228223 -3.05 13.05 virtualcards +invoice-obsidian 0:eae2564ef311 -3.05 13.05 50virtualcards +invoice-obsidian 0:cf02270203a4 -3.09 12.48 £100.00 +invoice-obsidian 0:33b5fc913817 -3.09 12.58 £20.00 +invoice-obsidian 0:8aec54fdb1a1 -3.09 12.49 £120.00 +invoice-obsidian 0:cc29e90932c5 -3.84 13.05 businessaccountmaintenance +invoice-obsidian 0:f1254de1a1d4 -3.84 13.05 monthlyaccountmaintenancefee +invoice-obsidian 0:8bf9ac7b27bd -3.88 12.68 £6.00 +invoice-obsidian 0:bff295cd3f97 -3.88 12.59 £36.00 +invoice-obsidian 0:d6577e95efba -0.09 0.11 subtotal +invoice-obsidian 0:4595e1b34cb1 -0.10 0.63 £730.00 +invoice-obsidian 0:eafa82a0eadf -0.14 0.63 £146.00 +invoice-obsidian 0:57a66d21eb1b -0.22 0.11 totaldue +invoice-obsidian 0:ad3ba615a506 -0.24 -0.59 £876.00 +invoice-obsidian 0:ab5aa97074c4 -0.13 0.08 notes +invoice-obsidian 0:0956d8d0441d 0.24 0.08 thankyouforchoosingkestrelbusine +invoice-obsidian 0:0b4d6f0e8783 0.24 0.08 thisinvoicecoversservicesandfeat +invoice-obsidian 0:02e483554647 0.25 0.08 toyourbusinessasofthedateofissue +invoice-obsidian 0:b439106fc5a1 0.26 0.08 ifyouhaveanyquestionsaboutthisin +invoice-obsidian 0:877ac656a147 0.27 0.08 pleasecontactusatar@kestrel.exam +invoice-obsidian 0:3c7ade679fdf -0.13 0.09 paymentdetails +invoice-obsidian 0:473fbeedb47c -0.65 0.11 pleasepaybybanktransfer +invoice-obsidian 0:59f2b74175d7 -0.64 0.11 totheaccountbelow. +invoice-obsidian 0:811f691f5582 -0.12 0.11 payee +invoice-obsidian 0:10aeacde20ff -0.13 0.11 sortcode +invoice-obsidian 0:a748c443f622 -0.19 0.08 04-00-75 +invoice-obsidian 0:f92a9c925024 -0.14 0.11 accountnumber +invoice-obsidian 0:ef797c8118f0 -0.20 0.08 12345678 +invoice-obsidian 0:52367a6622b1 -0.15 0.11 reference +invoice-obsidian 0:7c6ab37d83ef -0.22 0.08 thankyouforyourbusiness. +invoice-obsidian 0:a97667f07d1b -0.23 0.08 paymentisdueby10september2026. invoice-obsidian 0:7b14b8d2c5c4 -0.03 -0.51 page1of1 invoice-payments 0:b6c4ac412ac8 -0.02 0.10 meridian invoice-payments 0:52d6e3de4fa0 0.41 0.05 invoice invoice-payments 0:c0cc75b9cfdc -0.22 0.12 meridianpaymentsltd. -invoice-payments 0:c0cc75b9cfdc#1 -5.61 0.10 meridianpaymentsltd. +invoice-payments 0:c0cc75b9cfdc#1 -5.71 0.10 meridianpaymentsltd. invoice-payments 0:5eeaa101da6c -0.19 0.12 1harbourexchange invoice-payments 0:e3f6090f249b -0.23 0.12 canarywharf invoice-payments 0:1bb9adbf32ff -0.26 0.12 londone149ge @@ -3153,7 +3154,7 @@ invoice-payments 0:fb854bac39c8 -0.16 0.05 paymentterms invoice-payments 0:ac10f8c16320 -0.19 0.05 duedate invoice-payments 0:073c1634c496 -0.21 0.05 status invoice-payments 0:052ff4dff688 -0.04 -0.02 inv-2025-05-10472 -invoice-payments 0:052ff4dff688#1 -5.81 0.10 inv-2025-05-10472 +invoice-payments 0:052ff4dff688#1 -5.91 0.10 inv-2025-05-10472 invoice-payments 0:23a4c624cbda -0.01 -0.02 10may2025 invoice-payments 0:7b052c343b27 0.02 -0.02 1-30april2025 invoice-payments 0:018052c1dd59 0.04 -0.02 acct_4q8xtb2mkp @@ -3171,84 +3172,84 @@ invoice-payments 0:725a8f5062e7 0.13 0.00 shipto invoice-payments 0:9976f2392d8c 0.13 0.05 operationscentre invoice-payments 0:fc0e113402c7 0.10 0.05 7kingswaypark invoice-payments 0:a72c3f2308ed 0.07 0.05 leedsls126bd -invoice-payments 0:c9046f7a37ad 0.04 0.47 description -invoice-payments 0:1a7b308d8df6 0.04 0.38 quantity -invoice-payments 0:d1062d072acd 0.04 0.36 unitprice -invoice-payments 0:7c512b48ba8a 0.04 0.40 vat -invoice-payments 0:2da123241332 0.04 1.09 amount(gbp) -invoice-payments 0:3ab6c1099bcc -0.02 0.42 subscriptionbilling -invoice-payments 0:c8e69cd6e074 0.12 0.42 subscriptionmanagementandrecurri -invoice-payments 0:0c95c7ece1ce -0.04 0.42 billing -invoice-payments 0:96d6b62c061d -0.05 -0.21 £250.00 -invoice-payments 0:96d6b62c061d#1 -0.04 0.74 £250.00 -invoice-payments 0:dc934fe30a94 -0.05 0.26 20% -invoice-payments 0:dc934fe30a94#1 -0.10 0.26 20% -invoice-payments 0:dc934fe30a94#2 -0.78 0.26 20% -invoice-payments 0:dc934fe30a94#3 -2.14 0.26 20% -invoice-payments 0:dc934fe30a94#4 -3.50 0.26 20% -invoice-payments 0:dc934fe30a94#5 -4.86 0.26 20% -invoice-payments 0:0a9acaea6477 -0.07 0.42 paymentprocessing -invoice-payments 0:b8a3c21545b4 0.07 0.42 onlinecardpaymentsprocessing -invoice-payments 0:b42561a38a06 -0.09 0.42 (volumetier) -invoice-payments 0:351704ebff51 -0.10 -0.35 £1,180.00 -invoice-payments 0:351704ebff51#1 -0.09 0.77 £1,180.00 -invoice-payments 0:b3bc34f90a55 -0.78 0.42 fraudscreening -invoice-payments 0:ed051c6a1942 -0.74 0.42 advancedfraudscreeningandrules -invoice-payments 0:a0a787efd867 -0.78 -0.21 £320.00 -invoice-payments 0:a0a787efd867#1 -0.77 0.74 £320.00 -invoice-payments 0:34b75c1d0234 -2.14 0.42 companyformation -invoice-payments 0:bf45c494a8dc -2.10 0.42 incorporationandcompliancefiling -invoice-payments 0:629184210581 -2.14 -0.21 £180.00 -invoice-payments 0:629184210581#1 -2.13 0.74 £180.00 -invoice-payments 0:9427a01801d2 -3.50 0.42 in-personterminals -invoice-payments 0:882be821cf2e -3.46 0.42 terminalrentalandfirmwareupdates -invoice-payments 0:3c4459a5e4ec -3.50 -0.07 £39.00 -invoice-payments 0:5d16afda896e -3.49 0.74 £156.00 -invoice-payments 0:0036ebf2cfb2 -4.86 0.42 prioritysupport -invoice-payments 0:7ef1d2ff5e3a -4.82 0.42 namedengineer,one-hourresponse -invoice-payments 0:cf02270203a4 -4.86 -0.21 £100.00 -invoice-payments 0:cf02270203a4#1 -4.85 0.74 £100.00 -invoice-payments 0:3c7ade679fdf -5.58 0.14 paymentdetails -invoice-payments 0:182748d2fece -5.54 0.15 bankname -invoice-payments 0:758f4a6f175f -5.53 0.15 accountname -invoice-payments 0:10aeacde20ff -5.52 0.15 sortcode -invoice-payments 0:f92a9c925024 -5.51 0.15 accountnumber -invoice-payments 0:d53cd2cae33d -5.50 0.15 iban -invoice-payments 0:3f695692d5f1 -5.49 0.15 swift/bic -invoice-payments 0:52367a6622b1 -5.48 0.15 reference -invoice-payments 0:c66da4639881 -5.57 0.10 harbourbankplc -invoice-payments 0:2cd71c3c2603 -5.65 0.10 40-02-50 -invoice-payments 0:8fb8a81278c4 -5.69 0.10 71295408 -invoice-payments 0:48617b6d05d4 -5.73 0.10 gb29hrbk40025071295408 -invoice-payments 0:6929e6db6e1f -5.77 0.10 hrbkgb2l -invoice-payments 0:e4c4788968b2 -5.49 -0.01 subtotal(excl.vat) -invoice-payments 0:7ed180496d4e -5.48 -0.01 vatat20% -invoice-payments 0:751cbab81a3a -5.45 0.29 £2,186.00 -invoice-payments 0:9a5256946abd -5.44 0.89 £437.20 -invoice-payments 0:57a66d21eb1b -5.50 -0.01 totaldue -invoice-payments 0:5eb0b17220fa -5.44 -0.01 dueby14june2025 -invoice-payments 0:30d896eb989f -5.70 -0.83 £2,623.20 -invoice-payments 0:ab5aa97074c4 -5.29 0.14 notes -invoice-payments 0:241bcf576ac5 -5.27 0.14 thankyouforyourbusiness.thisinvo -invoice-payments 0:f912ca46bf39 -5.29 0.14 latepaymentmayincurinterestatthe -invoice-payments 0:73a09fec2c1a -5.25 0.10 paymentdueby14june2025 -invoice-payments 0:79df6c5bbc16 -5.27 0.10 pleaseincludetheinvoicenumberasp -invoice-payments 0:28b3008f693b -5.31 0.01 questions?we'reheretohelp. -invoice-payments 0:5b88ed40a689 -5.28 0.01 support@meridianpayments.example -invoice-payments 0:2e3891f6ba2f -5.27 0.01 39661900 +invoice-payments 0:c9046f7a37ad -0.06 0.47 description +invoice-payments 0:1a7b308d8df6 -0.06 0.38 quantity +invoice-payments 0:d1062d072acd -0.06 0.36 unitprice +invoice-payments 0:7c512b48ba8a -0.06 0.40 vat +invoice-payments 0:2da123241332 -0.06 1.09 amount(gbp) +invoice-payments 0:3ab6c1099bcc -0.12 0.42 subscriptionbilling +invoice-payments 0:c8e69cd6e074 0.02 0.42 subscriptionmanagementandrecurri +invoice-payments 0:0c95c7ece1ce -0.14 0.42 billing +invoice-payments 0:96d6b62c061d -0.15 -0.21 £250.00 +invoice-payments 0:96d6b62c061d#1 -0.14 0.74 £250.00 +invoice-payments 0:dc934fe30a94 -0.15 0.26 20% +invoice-payments 0:dc934fe30a94#1 -0.20 0.26 20% +invoice-payments 0:dc934fe30a94#2 -0.88 0.26 20% +invoice-payments 0:dc934fe30a94#3 -2.24 0.26 20% +invoice-payments 0:dc934fe30a94#4 -3.60 0.26 20% +invoice-payments 0:dc934fe30a94#5 -4.96 0.26 20% +invoice-payments 0:0a9acaea6477 -0.17 0.42 paymentprocessing +invoice-payments 0:b8a3c21545b4 -0.03 0.42 onlinecardpaymentsprocessing +invoice-payments 0:b42561a38a06 -0.19 0.42 (volumetier) +invoice-payments 0:351704ebff51 -0.20 -0.35 £1,180.00 +invoice-payments 0:351704ebff51#1 -0.19 0.77 £1,180.00 +invoice-payments 0:b3bc34f90a55 -0.88 0.42 fraudscreening +invoice-payments 0:ed051c6a1942 -0.84 0.42 advancedfraudscreeningandrules +invoice-payments 0:a0a787efd867 -0.88 -0.21 £320.00 +invoice-payments 0:a0a787efd867#1 -0.87 0.74 £320.00 +invoice-payments 0:34b75c1d0234 -2.24 0.42 companyformation +invoice-payments 0:bf45c494a8dc -2.20 0.42 incorporationandcompliancefiling +invoice-payments 0:629184210581 -2.24 -0.21 £180.00 +invoice-payments 0:629184210581#1 -2.23 0.74 £180.00 +invoice-payments 0:9427a01801d2 -3.60 0.42 in-personterminals +invoice-payments 0:882be821cf2e -3.56 0.42 terminalrentalandfirmwareupdates +invoice-payments 0:3c4459a5e4ec -3.60 -0.07 £39.00 +invoice-payments 0:5d16afda896e -3.59 0.74 £156.00 +invoice-payments 0:0036ebf2cfb2 -4.96 0.42 prioritysupport +invoice-payments 0:7ef1d2ff5e3a -4.92 0.42 namedengineer,one-hourresponse +invoice-payments 0:cf02270203a4 -4.96 -0.21 £100.00 +invoice-payments 0:cf02270203a4#1 -4.95 0.74 £100.00 +invoice-payments 0:3c7ade679fdf -5.68 0.14 paymentdetails +invoice-payments 0:182748d2fece -5.64 0.15 bankname +invoice-payments 0:758f4a6f175f -5.63 0.15 accountname +invoice-payments 0:10aeacde20ff -5.62 0.15 sortcode +invoice-payments 0:f92a9c925024 -5.61 0.15 accountnumber +invoice-payments 0:d53cd2cae33d -5.60 0.15 iban +invoice-payments 0:3f695692d5f1 -5.59 0.15 swift/bic +invoice-payments 0:52367a6622b1 -5.58 0.15 reference +invoice-payments 0:c66da4639881 -5.67 0.10 harbourbankplc +invoice-payments 0:2cd71c3c2603 -5.75 0.10 40-02-50 +invoice-payments 0:8fb8a81278c4 -5.79 0.10 71295408 +invoice-payments 0:48617b6d05d4 -5.83 0.10 gb29hrbk40025071295408 +invoice-payments 0:6929e6db6e1f -5.87 0.10 hrbkgb2l +invoice-payments 0:e4c4788968b2 -5.59 -0.01 subtotal(excl.vat) +invoice-payments 0:7ed180496d4e -5.58 -0.01 vatat20% +invoice-payments 0:751cbab81a3a -5.55 0.29 £2,186.00 +invoice-payments 0:9a5256946abd -5.54 0.89 £437.20 +invoice-payments 0:57a66d21eb1b -5.60 -0.01 totaldue +invoice-payments 0:5eb0b17220fa -5.54 -0.01 dueby14june2025 +invoice-payments 0:30d896eb989f -5.80 -0.83 £2,623.20 +invoice-payments 0:ab5aa97074c4 -5.49 0.14 notes +invoice-payments 0:241bcf576ac5 -5.47 0.14 thankyouforyourbusiness.thisinvo +invoice-payments 0:f912ca46bf39 -5.49 0.14 latepaymentmayincurinterestatthe +invoice-payments 0:73a09fec2c1a -5.45 0.10 paymentdueby14june2025 +invoice-payments 0:79df6c5bbc16 -5.47 0.10 pleaseincludetheinvoicenumberasp +invoice-payments 0:28b3008f693b -5.51 0.01 questions?we'reheretohelp. +invoice-payments 0:5b88ed40a689 -5.48 0.01 support@meridianpayments.example +invoice-payments 0:2e3891f6ba2f -5.47 0.01 39661900 invoice-payments 0:7b14b8d2c5c4 -0.04 -0.11 page1of1 invoice-platform 0:9817f28442bf 0.04 0.12 auroracloud invoice-platform 0:9817f28442bf#1 -1.41 0.14 auroracloud invoice-platform 0:52d6e3de4fa0 0.61 -0.26 invoice invoice-platform 0:1cf61cdc6464 0.06 0.13 auroracloudinc. -invoice-platform 0:1cf61cdc6464#1 -0.35 0.40 auroracloudinc. +invoice-platform 0:1cf61cdc6464#1 -0.45 0.40 auroracloudinc. invoice-platform 0:1cf61cdc6464#2 -1.38 0.25 auroracloudinc. invoice-platform 0:43315277b007 -0.40 0.13 500harbourstreet invoice-platform 0:d9065bfb8f59 -0.40 0.13 vancouver,bcv6c2w2 invoice-platform 0:408c7c5887a0 -0.41 0.13 canada invoice-platform 0:88a643f14708 0.18 0.21 aurora.example invoice-platform 0:f2cfc804c0f3 0.18 0.21 billing@aurora.example -invoice-platform 0:f2cfc804c0f3#1 -0.32 0.40 billing@aurora.example +invoice-platform 0:f2cfc804c0f3#1 -0.42 0.40 billing@aurora.example invoice-platform 0:799715f2b96e 0.19 0.21 +1604-555-0180 invoice-platform 0:719c55c7e988 -0.44 0.13 vatid:cabn842137755 invoice-platform 0:6282391a4cc1 -0.31 0.10 invoicenumber: @@ -3321,22 +3322,22 @@ invoice-platform 0:561b2814d3c0#1 -0.52 0.22 0.00 invoice-platform 0:efa8771baad9 -0.53 0.09 supportplan invoice-platform 0:9e81cd6e653a -0.50 0.09 standardresponse invoice-platform 0:13000a5d442c -0.50 0.35 paymentinformation -invoice-platform 0:944d398aea60 -0.36 0.44 bankname: -invoice-platform 0:d6c3cea2e943 -0.36 0.40 harbourbankofcanada -invoice-platform 0:0ecb5847ffa7 -0.35 0.44 accountname: -invoice-platform 0:6b4894c28363 -0.35 0.44 accountnumber: -invoice-platform 0:559c58c48948 -0.35 0.40 417802336 -invoice-platform 0:555043320c0c -0.34 0.44 swiftcode: -invoice-platform 0:5a986aa9e713 -0.34 0.40 hbcacat1 -invoice-platform 0:e47c9313aced -0.33 0.44 transitnumber: -invoice-platform 0:20b565bff5c3 -0.33 0.40 00812 -invoice-platform 0:f1b1597830d6 -0.33 0.44 institutionnumber: -invoice-platform 0:3c241d267414 -0.33 0.40 049 -invoice-platform 0:4f657c67e41a -0.32 0.44 accounttype: -invoice-platform 0:7522b6a6c098 -0.32 0.40 businesschequing -invoice-platform 0:fa0fbe194b51 -0.32 0.44 remittanceemail: -invoice-platform 0:b3ec04f337ed -0.42 0.35 includeyourbillingaccountid -invoice-platform 0:a11a3e122422 -0.43 0.35 onyourpaymentremittance. +invoice-platform 0:944d398aea60 -0.46 0.44 bankname: +invoice-platform 0:d6c3cea2e943 -0.46 0.40 harbourbankofcanada +invoice-platform 0:0ecb5847ffa7 -0.45 0.44 accountname: +invoice-platform 0:6b4894c28363 -0.45 0.44 accountnumber: +invoice-platform 0:559c58c48948 -0.45 0.40 417802336 +invoice-platform 0:555043320c0c -0.44 0.44 swiftcode: +invoice-platform 0:5a986aa9e713 -0.44 0.40 hbcacat1 +invoice-platform 0:e47c9313aced -0.43 0.44 transitnumber: +invoice-platform 0:20b565bff5c3 -0.43 0.40 00812 +invoice-platform 0:f1b1597830d6 -0.43 0.44 institutionnumber: +invoice-platform 0:3c241d267414 -0.43 0.40 049 +invoice-platform 0:4f657c67e41a -0.42 0.44 accounttype: +invoice-platform 0:7522b6a6c098 -0.42 0.40 businesschequing +invoice-platform 0:fa0fbe194b51 -0.42 0.44 remittanceemail: +invoice-platform 0:b3ec04f337ed -0.52 0.35 includeyourbillingaccountid +invoice-platform 0:a11a3e122422 -0.53 0.35 onyourpaymentremittance. invoice-platform 0:d6577e95efba -0.46 0.07 subtotal invoice-platform 0:6fb943a5640a -0.46 0.02 186.44 invoice-platform 0:26a72d1933a2 -0.45 0.07 tax(5%) @@ -3354,14 +3355,14 @@ invoice-subscription 0:0a36c1665b7e 0.28 0.12 halsteadsoftwareltd. invoice-subscription 0:6bc2056359b7 0.20 0.12 18chandlerrow invoice-subscription 0:776a7e9eb92a 0.22 0.12 leedsls14qt invoice-subscription 0:2474519f77a9 0.24 0.12 unitedkingdom -invoice-subscription 0:2474519f77a9#1 -0.70 0.12 unitedkingdom -invoice-subscription 0:2474519f77a9#2 -0.70 0.07 unitedkingdom +invoice-subscription 0:2474519f77a9#1 0.45 0.12 unitedkingdom +invoice-subscription 0:2474519f77a9#2 0.45 0.07 unitedkingdom invoice-subscription 0:bfdec553b85a 0.24 0.12 billing@halstead.example invoice-subscription 0:78acb3cb907b 0.27 0.12 www.halstead.example invoice-subscription 0:f1c030eb4329 0.29 0.12 vatnogb418227603 invoice-subscription 0:77ead61b5875 0.29 0.09 invoiceno invoice-subscription 0:0b0c0ee24de8 0.26 0.69 hs-inv-2026-0417 -invoice-subscription 0:0b0c0ee24de8#1 -0.07 0.88 hs-inv-2026-0417 +invoice-subscription 0:0b0c0ee24de8#1 0.63 0.88 hs-inv-2026-0417 invoice-subscription 0:8feaf8016bab 0.34 0.09 issuedate invoice-subscription 0:4d49cb78b810 0.32 0.62 27august2026 invoice-subscription 0:ac10f8c16320 0.39 0.09 duedate @@ -3371,77 +3372,77 @@ invoice-subscription 0:56a2e019b8aa 0.42 0.38 14days invoice-subscription 0:466e5b9cd57f 0.50 0.09 currency invoice-subscription 0:54f8e1b3fe44 0.47 0.31 gbp invoice-subscription 0:aeba3a7b3598 0.51 0.12 billto -invoice-subscription 0:7bfc2b791f41 -0.76 0.12 northlineconsultingltd -invoice-subscription 0:7bfc2b791f41#1 -0.76 0.07 northlineconsultingltd -invoice-subscription 0:bcb7024f74fe -0.75 0.12 attn:sarahmitchell -invoice-subscription 0:13dd937d2fe6 -0.73 0.12 21jubileeway -invoice-subscription 0:f9bab6a0b45b -0.72 0.12 londonse13ss +invoice-subscription 0:7bfc2b791f41 0.39 0.12 northlineconsultingltd +invoice-subscription 0:7bfc2b791f41#1 0.39 0.07 northlineconsultingltd +invoice-subscription 0:bcb7024f74fe 0.40 0.12 attn:sarahmitchell +invoice-subscription 0:13dd937d2fe6 0.42 0.12 21jubileeway +invoice-subscription 0:f9bab6a0b45b 0.43 0.12 londonse13ss invoice-subscription 0:725a8f5062e7 0.51 0.07 shipto -invoice-subscription 0:254289ce0191 -0.75 0.07 thefoundry,2ndfloor -invoice-subscription 0:84db1f48facb -0.73 0.07 17-19greatsuffolkstreet -invoice-subscription 0:e7a5f0717d99 -0.72 0.07 londonse10ns -invoice-subscription 0:c9046f7a37ad -0.61 0.12 description -invoice-subscription 0:32e8369a9c4f -0.61 0.13 qty -invoice-subscription 0:d1062d072acd -0.61 0.06 unitprice -invoice-subscription 0:7c512b48ba8a -0.61 0.12 vat -invoice-subscription 0:cf38d95c9c6b -0.61 0.05 amount -invoice-subscription 0:86705447c73d -0.32 0.12 halsteadworkspacepremium(10seats -invoice-subscription 0:0c8dc980db3f -0.32 0.18 £18.00 -invoice-subscription 0:dc934fe30a94 -0.32 0.09 20% -invoice-subscription 0:dc934fe30a94#1 -0.30 0.09 20% -invoice-subscription 0:dc934fe30a94#2 -0.28 0.09 20% -invoice-subscription 0:dc934fe30a94#3 -0.26 0.09 20% -invoice-subscription 0:dc934fe30a94#4 -0.24 0.09 20% -invoice-subscription 0:629184210581 -0.32 0.14 £180.00 -invoice-subscription 0:59df1d2b0f69 -0.30 0.12 hostedplatformservices -invoice-subscription 0:44c1ce3394d2 -0.30 0.16 £420.00 -invoice-subscription 0:44c1ce3394d2#1 -0.30 0.16 £420.00 -invoice-subscription 0:217bada1d20f -0.28 0.12 analyticsprolicences(5seats) -invoice-subscription 0:599cd58953ce -0.28 0.15 £8.40 -invoice-subscription 0:756b8c62fe05 -0.28 0.14 £42.00 -invoice-subscription 0:b055bcc305ed -0.26 0.12 prioritysupportplan -invoice-subscription 0:1077d7cede59 -0.26 0.13 £275.00 -invoice-subscription 0:1077d7cede59#1 -0.26 0.13 £275.00 -invoice-subscription 0:361537ef6a11 -0.24 0.12 voiceadd-on(5seats) -invoice-subscription 0:8bf9ac7b27bd -0.24 0.14 £6.00 -invoice-subscription 0:893d7480f763 -0.24 0.14 £30.00 -invoice-subscription 0:ab5aa97074c4 -0.05 0.12 notes -invoice-subscription 0:4440ed73b83f 0.73 0.12 thisinvoicecoverssoftwaresubscri -invoice-subscription 0:fffc319556fa 0.74 0.12 hostedservicesforthecurrentbilli -invoice-subscription 0:d6577e95efba -0.21 0.11 subtotal -invoice-subscription 0:adde9b2bd3ad -0.21 0.47 £947.00 -invoice-subscription 0:a52611c9261b -0.23 0.11 vat(20%) -invoice-subscription 0:14edcfc20351 -0.23 0.44 £189.40 -invoice-subscription 0:57a66d21eb1b -0.18 0.11 totaldue -invoice-subscription 0:cf1b68cc49ef -0.11 0.89 £1,136.40 -invoice-subscription 0:3c7ade679fdf 1.24 0.12 paymentdetails -invoice-subscription 0:56ed021beb35 -0.03 0.49 beneficiary -invoice-subscription 0:0b85f3c8ed04 -0.07 0.33 halsteadsoftwareltd -invoice-subscription 0:4381dc2ab142 -0.03 0.72 bank -invoice-subscription 0:6d50b2dd724f -0.07 0.84 northgatebank -invoice-subscription 0:10aeacde20ff -0.03 0.83 sortcode -invoice-subscription 0:b19b1415ef9b -0.07 0.94 40-05-30 -invoice-subscription 0:f92a9c925024 -0.03 0.94 accountnumber -invoice-subscription 0:ef797c8118f0 -0.07 0.97 12345678 -invoice-subscription 0:52367a6622b1 -0.03 0.86 reference -invoice-subscription 0:04f7247e8e99 -0.03 0.12 pleaseincludetheinvoicenumberast -invoice-subscription 0:7c6ab37d83ef 0.01 23.79 thankyouforyourbusiness. -invoice-subscription 0:354ffeb2bbc3 -0.03 23.79 paymentisdueby10september2026.if -invoice-subscription 0:7f7d98088133 -0.02 23.79 foranyqueries,pleasecontactbilli +invoice-subscription 0:254289ce0191 0.40 0.07 thefoundry,2ndfloor +invoice-subscription 0:84db1f48facb 0.42 0.07 17-19greatsuffolkstreet +invoice-subscription 0:e7a5f0717d99 0.43 0.07 londonse10ns +invoice-subscription 0:c9046f7a37ad 0.54 0.12 description +invoice-subscription 0:32e8369a9c4f 0.54 0.13 qty +invoice-subscription 0:d1062d072acd 0.54 0.06 unitprice +invoice-subscription 0:7c512b48ba8a 0.54 0.12 vat +invoice-subscription 0:cf38d95c9c6b 0.54 0.05 amount +invoice-subscription 0:86705447c73d 0.53 0.12 halsteadworkspacepremium(10seats +invoice-subscription 0:0c8dc980db3f 0.53 0.18 £18.00 +invoice-subscription 0:dc934fe30a94 0.53 0.09 20% +invoice-subscription 0:dc934fe30a94#1 0.55 0.09 20% +invoice-subscription 0:dc934fe30a94#2 0.57 0.09 20% +invoice-subscription 0:dc934fe30a94#3 0.59 0.09 20% +invoice-subscription 0:dc934fe30a94#4 0.61 0.09 20% +invoice-subscription 0:629184210581 0.53 0.14 £180.00 +invoice-subscription 0:59df1d2b0f69 0.55 0.12 hostedplatformservices +invoice-subscription 0:44c1ce3394d2 0.55 0.16 £420.00 +invoice-subscription 0:44c1ce3394d2#1 0.55 0.16 £420.00 +invoice-subscription 0:217bada1d20f 0.57 0.12 analyticsprolicences(5seats) +invoice-subscription 0:599cd58953ce 0.57 0.15 £8.40 +invoice-subscription 0:756b8c62fe05 0.57 0.14 £42.00 +invoice-subscription 0:b055bcc305ed 0.59 0.12 prioritysupportplan +invoice-subscription 0:1077d7cede59 0.59 0.13 £275.00 +invoice-subscription 0:1077d7cede59#1 0.59 0.13 £275.00 +invoice-subscription 0:361537ef6a11 0.61 0.12 voiceadd-on(5seats) +invoice-subscription 0:8bf9ac7b27bd 0.61 0.14 £6.00 +invoice-subscription 0:893d7480f763 0.61 0.14 £30.00 +invoice-subscription 0:ab5aa97074c4 0.80 0.12 notes +invoice-subscription 0:4440ed73b83f 0.38 0.12 thisinvoicecoverssoftwaresubscri +invoice-subscription 0:fffc319556fa 0.39 0.12 hostedservicesforthecurrentbilli +invoice-subscription 0:d6577e95efba 0.64 0.11 subtotal +invoice-subscription 0:adde9b2bd3ad 0.64 0.47 £947.00 +invoice-subscription 0:a52611c9261b 0.62 0.11 vat(20%) +invoice-subscription 0:14edcfc20351 0.62 0.44 £189.40 +invoice-subscription 0:57a66d21eb1b 0.67 0.11 totaldue +invoice-subscription 0:cf1b68cc49ef 0.74 0.89 £1,136.40 +invoice-subscription 0:3c7ade679fdf 0.79 0.12 paymentdetails +invoice-subscription 0:56ed021beb35 0.67 0.49 beneficiary +invoice-subscription 0:0b85f3c8ed04 0.63 0.33 halsteadsoftwareltd +invoice-subscription 0:4381dc2ab142 0.67 0.72 bank +invoice-subscription 0:6d50b2dd724f 0.63 0.84 northgatebank +invoice-subscription 0:10aeacde20ff 0.67 0.83 sortcode +invoice-subscription 0:b19b1415ef9b 0.63 0.94 40-05-30 +invoice-subscription 0:f92a9c925024 0.67 0.94 accountnumber +invoice-subscription 0:ef797c8118f0 0.63 0.97 12345678 +invoice-subscription 0:52367a6622b1 0.67 0.86 reference +invoice-subscription 0:04f7247e8e99 0.67 0.12 pleaseincludetheinvoicenumberast +invoice-subscription 0:7c6ab37d83ef 0.71 23.79 thankyouforyourbusiness. +invoice-subscription 0:354ffeb2bbc3 0.67 23.79 paymentisdueby10september2026.if +invoice-subscription 0:7f7d98088133 0.68 23.79 foranyqueries,pleasecontactbilli invoice-subscription 0:7b14b8d2c5c4 0.00 0.09 page1of1 invoice-workspace 0:07f15cde5b18 0.15 0.11 kestrel -invoice-workspace 0:07f15cde5b18#1 0.56 0.11 kestrel +invoice-workspace 0:07f15cde5b18#1 -0.54 0.11 kestrel invoice-workspace 0:52d6e3de4fa0 -0.16 0.60 invoice invoice-workspace 0:091019880d88 -0.37 0.13 kestrelcollaboration,inc. -invoice-workspace 0:091019880d88#1 0.17 0.06 kestrelcollaboration,inc. -invoice-workspace 0:091019880d88#2 0.16 0.06 kestrelcollaboration,inc. +invoice-workspace 0:091019880d88#1 -0.48 0.06 kestrelcollaboration,inc. +invoice-workspace 0:091019880d88#2 -0.94 0.06 kestrelcollaboration,inc. invoice-workspace 0:9167e0470dae -0.31 0.13 500howardstreet,6thfloor invoice-workspace 0:efa5e1529794 -0.28 0.13 sanfrancisco,ca94105 invoice-workspace 0:fd7321c405f8 -0.24 0.13 unitedstates invoice-workspace 0:d3c6f273c22d -0.24 0.13 vatid:us77-0560185 invoice-workspace 0:6282391a4cc1 -0.31 0.04 invoicenumber: invoice-workspace 0:b13757c9a6fc -0.30 -0.03 inv-2024-0003521 -invoice-workspace 0:b13757c9a6fc#1 -0.02 0.06 inv-2024-0003521 +invoice-workspace 0:b13757c9a6fc#1 -0.67 0.06 inv-2024-0003521 invoice-workspace 0:8d05f5d55191 -0.29 0.04 invoicedate: invoice-workspace 0:8da43dd45024 -0.27 -0.03 27may2024 invoice-workspace 0:d39366fa1423 -0.26 0.04 billingperiod: @@ -3452,7 +3453,7 @@ invoice-workspace 0:18e2cca1098e -0.21 0.04 paymentterms: invoice-workspace 0:98ec3d1fd5b9 -0.20 -0.03 net30 invoice-workspace 0:0e0fb0fc0939 -0.19 0.04 duedate: invoice-workspace 0:f1e2a60122bd -0.18 -0.03 26june2024 -invoice-workspace 0:f1e2a60122bd#1 -0.88 0.10 26june2024 +invoice-workspace 0:f1e2a60122bd#1 -0.53 0.10 26june2024 invoice-workspace 0:aeba3a7b3598 -0.18 0.10 billto invoice-workspace 0:45fe04dbae24 -0.22 0.10 brightfutureltd. invoice-workspace 0:45fe04dbae24#1 -0.22 0.02 brightfutureltd. @@ -3464,60 +3465,60 @@ invoice-workspace 0:c7a9cfdd1c55 -0.13 0.10 vatid:gb987654321 invoice-workspace 0:725a8f5062e7 -0.18 0.02 shipto invoice-workspace 0:6d835e737af6 -0.17 0.02 unit4,riversidepark invoice-workspace 0:555d5194cd4d -0.16 0.02 leedsls14ap -invoice-workspace 0:c9046f7a37ad 0.01 0.45 description -invoice-workspace 0:169240d91658 0.01 0.20 plan/service -invoice-workspace 0:32e8369a9c4f 0.01 0.21 qty -invoice-workspace 0:e2a9c81da5f6 0.01 0.22 unitprice(usd) -invoice-workspace 0:5dfb966b2bcf 0.01 0.36 amount(usd) -invoice-workspace 0:2bcc555090a1 -0.09 0.40 kestrelbusiness+ -invoice-workspace 0:68fad867a983 -0.04 0.40 workspacesubscription -invoice-workspace 0:e0b844887562 -0.03 0.53 business+annual -invoice-workspace 0:84906b0f4b73 -0.03 0.46 50users -invoice-workspace 0:5ee31a6284bc -0.03 0.44 8.75 -invoice-workspace 0:843d501d422c -0.03 0.47 437.50 -invoice-workspace 0:3007667b4e18 -0.16 0.40 enterprisekeymanagement -invoice-workspace 0:162e9c93c528 -0.11 0.40 customer-managedencryptionkeys -invoice-workspace 0:a33a54a73112 -0.10 0.46 add-on -invoice-workspace 0:d66c66a96157 -0.10 0.47 100.00 -invoice-workspace 0:d66c66a96157#1 -0.10 0.47 100.00 -invoice-workspace 0:0036ebf2cfb2 -0.23 0.40 prioritysupport -invoice-workspace 0:51833276172f -0.18 0.40 namedengineerandresponsetarget -invoice-workspace 0:fe6d3468cf5c -0.17 0.50 standard -invoice-workspace 0:a99210875f11 -0.17 0.46 50.00 -invoice-workspace 0:a99210875f11#1 -0.17 0.45 50.00 -invoice-workspace 0:14209e8ccd53 -0.30 0.40 workflowautomation -invoice-workspace 0:31be3ff05457 -0.25 0.40 templatesandscheduledruns -invoice-workspace 0:7f0f70e643bc -0.24 0.49 included -invoice-workspace 0:561b2814d3c0 -0.24 0.44 0.00 -invoice-workspace 0:561b2814d3c0#1 -0.24 0.48 0.00 -invoice-workspace 0:561b2814d3c0#2 -0.24 0.29 0.00 -invoice-workspace 0:3c7ade679fdf 0.12 0.08 paymentdetails -invoice-workspace 0:944d398aea60 0.21 0.12 bankname: -invoice-workspace 0:a18e9fdf120e 0.21 0.06 bayunionbank,n.a. -invoice-workspace 0:0ecb5847ffa7 0.17 0.12 accountname: -invoice-workspace 0:6b4894c28363 0.13 0.12 accountnumber: -invoice-workspace 0:ab92799f9bc7 0.13 0.06 000000123456789 -invoice-workspace 0:c1390f638bd3 0.09 0.12 routing(aba): -invoice-workspace 0:1f873cdde0ca 0.09 0.06 021000021 -invoice-workspace 0:e58256751597 0.06 0.12 swift/bic: -invoice-workspace 0:0fdf54f117f8 0.06 0.06 bayuus33 -invoice-workspace 0:967e0b6ca4b9 0.02 0.12 currency: -invoice-workspace 0:d60fbd8718ec 0.02 0.06 usd -invoice-workspace 0:c608665436db -0.02 0.12 reference: -invoice-workspace 0:3db3fa89ea2c -0.06 0.12 bankaddress: -invoice-workspace 0:b1645851e755 -0.06 0.06 1marketplaza,sanfrancisco -invoice-workspace 0:9b600d1211c8 0.88 0.14 pleaseincludetheinvoicenumberiny -invoice-workspace 0:415eb9e42f41 -0.38 0.14 reference. -invoice-workspace 0:d6577e95efba -0.24 0.13 subtotal -invoice-workspace 0:460dd5bae888 -0.24 0.40 587.50 -invoice-workspace 0:2ee4d3de4ddf -0.24 0.13 tax(0%) -invoice-workspace 0:57a66d21eb1b -0.31 0.13 totaldue -invoice-workspace 0:ad00e93ce79a -0.39 0.62 usd587.50 -invoice-workspace 0:b0553f008513 -0.77 0.10 paymentdueby -invoice-workspace 0:08775a92bfca 0.19 0.12 thankyouforusingkestrel. -invoice-workspace 0:18e82fbd48a3 0.26 0.12 questionsaboutthisinvoice?reachu -invoice-workspace 0:3c72ba0e1eb8 0.13 0.06 500howardstreet,6thfloor,sanfran -invoice-workspace 0:9e2917e23527 0.12 -0.12 kestrel.example +invoice-workspace 0:c9046f7a37ad -0.09 0.45 description +invoice-workspace 0:169240d91658 -0.09 0.20 plan/service +invoice-workspace 0:32e8369a9c4f -0.09 0.21 qty +invoice-workspace 0:e2a9c81da5f6 -0.09 0.22 unitprice(usd) +invoice-workspace 0:5dfb966b2bcf -0.09 0.36 amount(usd) +invoice-workspace 0:2bcc555090a1 -0.19 0.40 kestrelbusiness+ +invoice-workspace 0:68fad867a983 -0.14 0.40 workspacesubscription +invoice-workspace 0:e0b844887562 -0.13 0.53 business+annual +invoice-workspace 0:84906b0f4b73 -0.13 0.46 50users +invoice-workspace 0:5ee31a6284bc -0.13 0.44 8.75 +invoice-workspace 0:843d501d422c -0.13 0.47 437.50 +invoice-workspace 0:3007667b4e18 -0.26 0.40 enterprisekeymanagement +invoice-workspace 0:162e9c93c528 -0.21 0.40 customer-managedencryptionkeys +invoice-workspace 0:a33a54a73112 -0.20 0.46 add-on +invoice-workspace 0:d66c66a96157 -0.20 0.47 100.00 +invoice-workspace 0:d66c66a96157#1 -0.20 0.47 100.00 +invoice-workspace 0:0036ebf2cfb2 -0.33 0.40 prioritysupport +invoice-workspace 0:51833276172f -0.28 0.40 namedengineerandresponsetarget +invoice-workspace 0:fe6d3468cf5c -0.27 0.50 standard +invoice-workspace 0:a99210875f11 -0.27 0.46 50.00 +invoice-workspace 0:a99210875f11#1 -0.27 0.45 50.00 +invoice-workspace 0:14209e8ccd53 -0.40 0.40 workflowautomation +invoice-workspace 0:31be3ff05457 -0.35 0.40 templatesandscheduledruns +invoice-workspace 0:7f0f70e643bc -0.34 0.49 included +invoice-workspace 0:561b2814d3c0 -0.34 0.44 0.00 +invoice-workspace 0:561b2814d3c0#1 -0.34 0.48 0.00 +invoice-workspace 0:561b2814d3c0#2 -0.34 0.29 0.00 +invoice-workspace 0:3c7ade679fdf -0.43 0.08 paymentdetails +invoice-workspace 0:944d398aea60 -0.44 0.12 bankname: +invoice-workspace 0:a18e9fdf120e -0.44 0.06 bayunionbank,n.a. +invoice-workspace 0:0ecb5847ffa7 -0.48 0.12 accountname: +invoice-workspace 0:6b4894c28363 -0.52 0.12 accountnumber: +invoice-workspace 0:ab92799f9bc7 -0.52 0.06 000000123456789 +invoice-workspace 0:c1390f638bd3 -0.56 0.12 routing(aba): +invoice-workspace 0:1f873cdde0ca -0.56 0.06 021000021 +invoice-workspace 0:e58256751597 -0.59 0.12 swift/bic: +invoice-workspace 0:0fdf54f117f8 -0.59 0.06 bayuus33 +invoice-workspace 0:967e0b6ca4b9 -0.63 0.12 currency: +invoice-workspace 0:d60fbd8718ec -0.63 0.06 usd +invoice-workspace 0:c608665436db -0.67 0.12 reference: +invoice-workspace 0:3db3fa89ea2c -0.71 0.12 bankaddress: +invoice-workspace 0:b1645851e755 -0.71 0.06 1marketplaza,sanfrancisco +invoice-workspace 0:9b600d1211c8 0.23 0.14 pleaseincludetheinvoicenumberiny +invoice-workspace 0:415eb9e42f41 -1.03 0.14 reference. +invoice-workspace 0:d6577e95efba -0.34 0.13 subtotal +invoice-workspace 0:460dd5bae888 -0.34 0.40 587.50 +invoice-workspace 0:2ee4d3de4ddf -0.34 0.13 tax(0%) +invoice-workspace 0:57a66d21eb1b -0.41 0.13 totaldue +invoice-workspace 0:ad00e93ce79a -0.49 0.62 usd587.50 +invoice-workspace 0:b0553f008513 -0.42 0.10 paymentdueby +invoice-workspace 0:08775a92bfca -0.91 0.12 thankyouforusingkestrel. +invoice-workspace 0:18e82fbd48a3 -0.84 0.12 questionsaboutthisinvoice?reachu +invoice-workspace 0:3c72ba0e1eb8 -0.97 0.06 500howardstreet,6thfloor,sanfran +invoice-workspace 0:9e2917e23527 -0.98 -0.12 kestrel.example invoice-workspace 0:7b14b8d2c5c4 -0.05 -0.13 page1of1 letter-blue_banner 0:8f1010120ed6 0.42 1.90 jordanrivera letter-blue_banner 0:8f1010120ed6#1 -0.02 0.10 jordanrivera @@ -3530,15 +3531,15 @@ letter-blue_banner 0:eae27893a255 -0.42 0.10 therestoftheteam. letter-blue_banner 0:a71e98216baa -0.08 0.10 iwouldwelcometheopportunitytobri letter-blue_banner 0:80a6a628ad52 -0.05 0.10 sincerely, letter-boxed_sections 0:8f1010120ed6 0.46 2.20 jordanrivera -letter-boxed_sections 0:8f1010120ed6#1 -0.37 0.10 jordanrivera -letter-boxed_sections 0:8d7a2cca3060 -0.12 0.12 +442055551000|jordan.rivera@exam -letter-boxed_sections 0:bef81b541365 -0.41 0.10 dearhiringteamatnorthwindsystems -letter-boxed_sections 0:ab54410ead82 -0.71 0.10 iamexcitedtosharemyinterestinthe -letter-boxed_sections 0:9185168d2cf8 -0.70 0.10 document-generationsystemsthatba -letter-boxed_sections 0:5fb2802723b6 -0.70 0.10 ienjoytranslatingfuzzyworkflowre -letter-boxed_sections 0:dab2d688b7ab -0.69 0.10 adoptioneasierfortherestofthetea -letter-boxed_sections 0:a71e98216baa -0.39 0.10 iwouldwelcometheopportunitytobri -letter-boxed_sections 0:80a6a628ad52 -0.38 0.10 sincerely, +letter-boxed_sections 0:8f1010120ed6#1 0.33 0.10 jordanrivera +letter-boxed_sections 0:8d7a2cca3060 0.23 0.12 +442055551000|jordan.rivera@exam +letter-boxed_sections 0:bef81b541365 0.29 0.10 dearhiringteamatnorthwindsystems +letter-boxed_sections 0:ab54410ead82 -0.01 0.10 iamexcitedtosharemyinterestinthe +letter-boxed_sections 0:9185168d2cf8 0.00 0.10 document-generationsystemsthatba +letter-boxed_sections 0:5fb2802723b6 0.00 0.10 ienjoytranslatingfuzzyworkflowre +letter-boxed_sections 0:dab2d688b7ab 0.01 0.10 adoptioneasierfortherestofthetea +letter-boxed_sections 0:a71e98216baa 0.31 0.10 iwouldwelcometheopportunitytobri +letter-boxed_sections 0:80a6a628ad52 0.32 0.10 sincerely, letter-centered_headline 0:8f1010120ed6 -0.50 2.39 jordanrivera letter-centered_headline 0:8f1010120ed6#1 -0.06 0.10 jordanrivera letter-centered_headline 0:2d58f0cadc2d -0.18 1.40 platformengineer @@ -3581,20 +3582,20 @@ letter-editorial_blue 0:dda41d31bb3c -0.15 0.10 thatmakeadoptioneasierfortherest letter-editorial_blue 0:a71e98216baa 0.16 0.10 iwouldwelcometheopportunitytobri letter-editorial_blue 0:80a6a628ad52 0.16 0.10 sincerely, letter-engineering_resume 0:8f1010120ed6 0.15 15.10 jordanrivera -letter-engineering_resume 0:8f1010120ed6#1 -1.41 0.10 jordanrivera +letter-engineering_resume 0:8f1010120ed6#1 -0.16 0.10 jordanrivera letter-engineering_resume 0:2d58f0cadc2d -0.25 15.10 platformengineer letter-engineering_resume 0:fbeea547d99e -0.21 15.31 london,uk letter-engineering_resume 0:89674e6f130e -0.20 15.34 +442055551000 letter-engineering_resume 0:e0f850305ded -0.19 15.20 jordan.rivera@example.com letter-engineering_resume 0:84308bea4540 -0.18 15.95 linkedin letter-engineering_resume 0:c0b0109d9439 -0.17 15.85 github -letter-engineering_resume 0:bef81b541365 -1.40 0.10 dearhiringteamatnorthwindsystems -letter-engineering_resume 0:c5331fbe74e1 -1.67 0.10 iamexcitedtosharemyinterestinthe -letter-engineering_resume 0:f27264b519fd -1.65 0.10 balancepublicapidesign,renderqua -letter-engineering_resume 0:b98ace48a28b -1.66 0.10 ienjoytranslatingfuzzyworkflowre -letter-engineering_resume 0:30edab94d52e -1.64 0.10 oftheteam. -letter-engineering_resume 0:a71e98216baa -1.40 0.10 iwouldwelcometheopportunitytobri -letter-engineering_resume 0:80a6a628ad52 -1.41 0.10 sincerely, +letter-engineering_resume 0:bef81b541365 -0.15 0.10 dearhiringteamatnorthwindsystems +letter-engineering_resume 0:c5331fbe74e1 -0.42 0.10 iamexcitedtosharemyinterestinthe +letter-engineering_resume 0:f27264b519fd -0.40 0.10 balancepublicapidesign,renderqua +letter-engineering_resume 0:b98ace48a28b -0.41 0.10 ienjoytranslatingfuzzyworkflowre +letter-engineering_resume 0:30edab94d52e -0.39 0.10 oftheteam. +letter-engineering_resume 0:a71e98216baa -0.15 0.10 iwouldwelcometheopportunitytobri +letter-engineering_resume 0:80a6a628ad52 -0.16 0.10 sincerely, letter-executive 0:8f1010120ed6 -0.50 0.10 jordanrivera letter-executive 0:8f1010120ed6#1 -0.10 0.10 jordanrivera letter-executive 0:89ff05847e96 -0.28 0.10 london,uk|+442055551000 @@ -3618,17 +3619,17 @@ letter-mint-editorial-letter 0:dd474e249222 0.29 0.10 makeadoptioneasierforthere letter-mint-editorial-letter 0:a71e98216baa -0.16 0.10 iwouldwelcometheopportunitytobri letter-mint-editorial-letter 0:80a6a628ad52 -0.16 0.10 sincerely, letter-modern_professional 0:8f1010120ed6 0.00 0.16 jordanrivera -letter-modern_professional 0:8f1010120ed6#1 -0.13 0.10 jordanrivera +letter-modern_professional 0:8f1010120ed6#1 0.22 0.10 jordanrivera letter-modern_professional 0:89ff05847e96 0.14 0.16 london,uk|+442055551000 letter-modern_professional 0:8817bf9310b6 0.11 0.10 jordan.rivera@example.com|linked -letter-modern_professional 0:bef81b541365 -0.13 0.10 dearhiringteamatnorthwindsystems -letter-modern_professional 0:c65db8c80e17 -0.43 0.10 iamexcitedtosharemyinterestinthe -letter-modern_professional 0:c8d01ef84078 -0.43 0.10 reusabledocument-generationsyste -letter-modern_professional 0:2e5ddee14dbc -0.43 0.10 ienjoytranslatingfuzzyworkflowre -letter-modern_professional 0:906501a5e847 -0.43 0.10 examplesthatmakeadoptioneasierfo -letter-modern_professional 0:7c5a9817c868 -0.43 0.10 iwouldwelcometheopportunitytobri -letter-modern_professional 0:4012eb4b05db -0.43 0.10 group. -letter-modern_professional 0:80a6a628ad52 -0.13 0.10 sincerely, +letter-modern_professional 0:bef81b541365 0.22 0.10 dearhiringteamatnorthwindsystems +letter-modern_professional 0:c65db8c80e17 -0.08 0.10 iamexcitedtosharemyinterestinthe +letter-modern_professional 0:c8d01ef84078 -0.08 0.10 reusabledocument-generationsyste +letter-modern_professional 0:2e5ddee14dbc -0.08 0.10 ienjoytranslatingfuzzyworkflowre +letter-modern_professional 0:906501a5e847 -0.08 0.10 examplesthatmakeadoptioneasierfo +letter-modern_professional 0:7c5a9817c868 -0.08 0.10 iwouldwelcometheopportunitytobri +letter-modern_professional 0:4012eb4b05db -0.08 0.10 group. +letter-modern_professional 0:80a6a628ad52 0.22 0.10 sincerely, letter-monogram_sidebar 0:136c67657614 -0.38 2.82 jordan letter-monogram_sidebar 0:8ba35ebe3d5c -0.37 2.85 rivera letter-monogram_sidebar 0:2d58f0cadc2d -0.19 0.13 platformengineer @@ -3656,11 +3657,11 @@ letter-nordic_clean 0:26e89af4523d -0.38 0.10 ienjoytranslatingfuzzyworkflowre letter-nordic_clean 0:27c5581ffbbc -0.39 0.10 restoftheteam. letter-nordic_clean 0:a71e98216baa -0.14 0.10 iwouldwelcometheopportunitytobri letter-nordic_clean 0:80a6a628ad52 -0.14 0.10 sincerely, -letter-panel 0:8f1010120ed6 -0.40 8.57 jordanrivera +letter-panel 0:8f1010120ed6 -0.65 8.57 jordanrivera letter-panel 0:8f1010120ed6#1 0.16 0.10 jordanrivera -letter-panel 0:2d58f0cadc2d 0.12 8.27 platformengineer -letter-panel 0:89ff05847e96 0.19 8.54 london,uk|+442055551000 -letter-panel 0:8817bf9310b6 0.21 8.55 jordan.rivera@example.com|linked +letter-panel 0:2d58f0cadc2d -0.13 8.27 platformengineer +letter-panel 0:89ff05847e96 -0.06 8.54 london,uk|+442055551000 +letter-panel 0:8817bf9310b6 -0.04 8.55 jordan.rivera@example.com|linked letter-panel 0:bef81b541365 0.01 0.10 dearhiringteamatnorthwindsystems letter-panel 0:ab54410ead82 -0.17 0.10 iamexcitedtosharemyinterestinthe letter-panel 0:9185168d2cf8 -0.15 0.10 document-generationsystemsthatba @@ -3714,43 +3715,43 @@ proposal-editorial 0:53fcd88ebb00 0.57 0.10 cohesivebrandsystemandamodern,co proposal-editorial 0:95bad9757a67 0.57 0.10 outcomewillbeaclear,confidentpre proposal-editorial 0:8863e2b998da 0.57 0.10 improvesengagement,andsupportsyo proposal-editorial 0:f16c2c2f1999 -0.92 0.10 projectgoals -proposal-editorial 0:c008ab0ba85f -0.19 0.10 projectduration -proposal-editorial 0:5a6b4bf425f2 -0.41 0.10 6weeks -proposal-editorial 0:7aa73e5c14d3 -0.12 0.10 startwindow -proposal-editorial 0:6fcb2d3f02ba -0.33 0.10 september2026 -proposal-editorial 0:185e8dc84248 -0.05 0.10 primarycontact -proposal-editorial 0:59d00e0c1b99 -0.26 0.10 projectlead -proposal-editorial 0:4190fd3a8d72 -0.01 0.10 proposalvalidity -proposal-editorial 0:56a2e019b8aa -0.22 0.10 14days -proposal-editorial 0:265e93f6b9da -0.05 0.10 (until8september2026) -proposal-editorial 0:e2ea93b97611 1.05 0.05 strengthenbrand -proposal-editorial 0:7d95098b921b 0.05 0.05 credibilityandvisual -proposal-editorial 0:218e304f8b84 -0.95 0.05 consistency. -proposal-editorial 0:35597cc9803f 1.05 0.06 improvewebsite -proposal-editorial 0:83f63137756b 0.05 0.06 usabilityanddrive -proposal-editorial 0:cce9fba37d4e -0.95 0.06 meaningfulaction. -proposal-editorial 0:59aaadaf0c54 1.05 0.06 communicateyour -proposal-editorial 0:30193022f687 0.05 0.06 valueclearlyacrossall -proposal-editorial 0:04b5995c746f -0.95 0.06 touchpoints. -proposal-editorial 0:b45d848fe1b6 1.05 0.07 buildascalabledigital -proposal-editorial 0:e8228bfeba0e 0.05 0.07 foundationforfuture -proposal-editorial 0:1fa35c7a1402 -0.95 0.07 growth. -proposal-editorial 0:bc981abcdf59 -1.43 0.10 scopeofwork -proposal-editorial 0:28450edd9a4f -0.35 0.05 discovery&research -proposal-editorial 0:ce9012b74aa2 -0.10 0.08 stakeholderinterviews,brandaudit -proposal-editorial 0:730c3e278933 -0.38 0.08 audienceinsightstoinformstrategy -proposal-editorial 0:12bff3036b66 -0.26 0.05 visualidentityrefinement -proposal-editorial 0:937ad523a90c -0.01 0.08 refinelogosystem,colorpalette,ty -proposal-editorial 0:9b232e66f46c -0.29 0.08 guidelinesforacohesive,modernide -proposal-editorial 0:fc5134bf5fd1 -0.17 0.05 websiteux/uidesign -proposal-editorial 0:5d58b01c7096 0.08 0.08 designaresponsive,accessibility- -proposal-editorial 0:5d6068f6a879 -0.20 0.08 navigationandclearconversionpath -proposal-editorial 0:32001e20b2ed -0.08 0.05 contentstructure&messaging -proposal-editorial 0:b3c948ec3e36 0.17 0.08 definesitearchitecture,keymessag -proposal-editorial 0:231428fde7aa -0.11 0.08 communicatevalueandbuildtrust. -proposal-editorial 0:8c7703bb6fb7 0.01 0.05 launchsupport -proposal-editorial 0:34f9fe468474 0.26 0.08 developerhandoff,qasupport,train -proposal-editorial 0:2b4cf15f6f16 -0.02 0.08 toensureasmoothlaunch. +proposal-editorial 0:c008ab0ba85f 0.16 0.10 projectduration +proposal-editorial 0:5a6b4bf425f2 -0.05 0.10 6weeks +proposal-editorial 0:7aa73e5c14d3 0.23 0.10 startwindow +proposal-editorial 0:6fcb2d3f02ba 0.02 0.10 september2026 +proposal-editorial 0:185e8dc84248 0.30 0.10 primarycontact +proposal-editorial 0:59d00e0c1b99 0.09 0.10 projectlead +proposal-editorial 0:4190fd3a8d72 0.35 0.10 proposalvalidity +proposal-editorial 0:56a2e019b8aa 0.13 0.10 14days +proposal-editorial 0:265e93f6b9da 0.30 0.10 (until8september2026) +proposal-editorial 0:e2ea93b97611 1.75 0.05 strengthenbrand +proposal-editorial 0:7d95098b921b 0.75 0.05 credibilityandvisual +proposal-editorial 0:218e304f8b84 -0.25 0.05 consistency. +proposal-editorial 0:35597cc9803f 1.75 0.06 improvewebsite +proposal-editorial 0:83f63137756b 0.75 0.06 usabilityanddrive +proposal-editorial 0:cce9fba37d4e -0.25 0.06 meaningfulaction. +proposal-editorial 0:59aaadaf0c54 1.75 0.06 communicateyour +proposal-editorial 0:30193022f687 0.75 0.06 valueclearlyacrossall +proposal-editorial 0:04b5995c746f -0.25 0.06 touchpoints. +proposal-editorial 0:b45d848fe1b6 1.75 0.07 buildascalabledigital +proposal-editorial 0:e8228bfeba0e 0.75 0.07 foundationforfuture +proposal-editorial 0:1fa35c7a1402 -0.25 0.07 growth. +proposal-editorial 0:bc981abcdf59 -0.73 0.10 scopeofwork +proposal-editorial 0:28450edd9a4f 0.35 0.05 discovery&research +proposal-editorial 0:ce9012b74aa2 0.60 0.08 stakeholderinterviews,brandaudit +proposal-editorial 0:730c3e278933 0.32 0.08 audienceinsightstoinformstrategy +proposal-editorial 0:12bff3036b66 0.44 0.05 visualidentityrefinement +proposal-editorial 0:937ad523a90c 0.69 0.08 refinelogosystem,colorpalette,ty +proposal-editorial 0:9b232e66f46c 0.41 0.08 guidelinesforacohesive,modernide +proposal-editorial 0:fc5134bf5fd1 0.53 0.05 websiteux/uidesign +proposal-editorial 0:5d58b01c7096 0.78 0.08 designaresponsive,accessibility- +proposal-editorial 0:5d6068f6a879 0.50 0.08 navigationandclearconversionpath +proposal-editorial 0:32001e20b2ed 0.62 0.05 contentstructure&messaging +proposal-editorial 0:b3c948ec3e36 0.87 0.08 definesitearchitecture,keymessag +proposal-editorial 0:231428fde7aa 0.59 0.08 communicatevalueandbuildtrust. +proposal-editorial 0:8c7703bb6fb7 0.71 0.05 launchsupport +proposal-editorial 0:34f9fe468474 0.96 0.08 developerhandoff,qasupport,train +proposal-editorial 0:2b4cf15f6f16 0.68 0.08 toensureasmoothlaunch. proposal-editorial 0:026890c58de9 0.01 0.10 northlinestudio|northlinestudio. proposal-editorial 1:e35c32bb5ed8 -46.41 0.10 deliverables proposal-editorial 1:23eb79a19b39 -45.38 0.60 brandstrategysummary @@ -3819,11 +3820,11 @@ proposal-editorial 1:566f68df6dd8 -44.99 0.14 finalpayment. proposal-editorial 1:06ebb5670fa8 -45.31 0.62 ownershipofallfinaldeliverables proposal-editorial 1:deda6d86d965 -44.96 0.14 transferstoasterahealthco.after proposal-editorial 1:aaa7d3e9affb -45.38 0.14 fullpaymentisreceived. -proposal-editorial 1:c1514c6cdad1 -45.64 9.50 acceptance -proposal-editorial 1:893663b06769 -44.61 9.50 bysigningbelow,youagreetothescop -proposal-editorial 1:df16232de5b9 -44.62 9.50 acceptedby: -proposal-editorial 1:f089d24d7cf3 -44.62 9.38 signature: -proposal-editorial 1:c74c9cd82f13 -44.62 9.24 date: +proposal-editorial 1:c1514c6cdad1 -45.29 9.50 acceptance +proposal-editorial 1:893663b06769 -44.26 9.50 bysigningbelow,youagreetothescop +proposal-editorial 1:df16232de5b9 -44.27 9.50 acceptedby: +proposal-editorial 1:f089d24d7cf3 -44.27 9.38 signature: +proposal-editorial 1:c74c9cd82f13 -44.27 9.24 date: proposal-editorial 1:026890c58de9 0.01 0.10 northlinestudio|northlinestudio. proposal-indigo 0:07f15cde5b18 0.14 0.08 kestrel proposal-indigo 0:ecd1378bc9dc 0.13 -0.43 proposal @@ -3898,47 +3899,47 @@ proposal-indigo 0:29208032c874 0.72 0.05 kestrel.example/business|busines proposal-modern 0:ecd1378bc9dc 0.00 16.10 proposal proposal-modern 0:f592a683c61d 0.27 16.10 documentplatformconsolidation proposal-modern 0:bbe07492ee1f 0.32 16.10 proposalgc-p-2026-014prepared02a -proposal-modern 0:566835ed7fba -0.07 12.35 executivesummary -proposal-modern 0:7ccf0e6c59fa -0.10 12.35 aphasedengagementtoretireper-tea -proposal-modern 0:75857a458999 -0.42 0.10 from -proposal-modern 0:c26c22b94338 -0.45 0.10 graphcomposestudio -proposal-modern 0:2a08ce5567fb -0.72 0.10 18layoutstreet -proposal-modern 0:fbeea547d99e -0.75 0.10 london,uk -proposal-modern 0:3c8401edb4cc -0.77 0.10 hello@graphcompose.dev -proposal-modern 0:89674e6f130e -0.80 0.10 +442055551000 -proposal-modern 0:213a61c7aeb6 -0.82 0.10 graphcompose.dev -proposal-modern 0:f890faef907f -0.45 0.11 northwindsystems -proposal-modern 0:577a7fcdaa02 -0.72 0.11 attn:procurement -proposal-modern 0:91eefd794f79 -0.75 0.11 410marketavenue -proposal-modern 0:3daace874084 -0.77 0.11 procurement@northwind.example -proposal-modern 0:5f161c914988 -0.41 0.10 scope -proposal-modern 0:9e580657f485 -0.57 0.10 discovery,architecture,andarefer -proposal-modern 0:cec9111de36d -0.41 0.10 approach -proposal-modern 0:3215ea3be6d9 -0.57 0.10 iterativedeliverywithweeklycheck -proposal-modern 0:94d192b3a326 -0.41 0.10 timeline -proposal-modern 0:02195b8e9896 -0.57 0.40 phase -proposal-modern 0:caa79af4db67 -0.57 0.35 duration -proposal-modern 0:41ffd8b76afc -0.57 0.35 details -proposal-modern 0:fa44132b238e -0.50 0.40 discovery -proposal-modern 0:fa44132b238e#1 -0.50 0.40 discovery -proposal-modern 0:b183847fe9f8 -0.50 0.35 2weeks -proposal-modern 0:4b20bfb69ca7 -0.50 0.35 stakeholderinterviews+audit -proposal-modern 0:44575cf5b285 -0.50 0.40 build -proposal-modern 0:44575cf5b285#1 -0.50 0.40 build -proposal-modern 0:5a6b4bf425f2 -0.50 0.35 6weeks -proposal-modern 0:7a802048127d -0.50 0.35 engine+templatemigration -proposal-modern 0:f9b21c4bda58 -0.41 0.10 investment -proposal-modern 0:4a33eacd5fa6 -0.57 0.40 item -proposal-modern 0:c9046f7a37ad -0.57 0.35 description -proposal-modern 0:cf38d95c9c6b -0.57 1.42 amount -proposal-modern 0:fe9b6b4f133b -0.50 0.35 workshops+auditgbp6,000 -proposal-modern 0:62e788ae3916 -0.50 0.35 engine+templatesgbp24,000 -proposal-modern 0:11239872d178 -0.60 0.40 total -proposal-modern 0:1c3065490625 -0.60 1.42 gbp30,000 -proposal-modern 0:63feb7230a5d -0.43 0.10 acceptanceterms -proposal-modern 0:35046a9f5675 -0.50 9.60 •50%onsignature,50%ondelivery. -proposal-modern 0:f03c1877ea2b -0.50 9.60 •validfor30daysfromthepreparedda -proposal-modern 0:90572e911376 -0.58 0.10 thankyouforconsideringgraphcompo +proposal-modern 0:566835ed7fba 0.23 12.35 executivesummary +proposal-modern 0:7ccf0e6c59fa 0.20 12.35 aphasedengagementtoretireper-tea +proposal-modern 0:75857a458999 0.18 0.10 from +proposal-modern 0:c26c22b94338 0.15 0.10 graphcomposestudio +proposal-modern 0:2a08ce5567fb -0.12 0.10 18layoutstreet +proposal-modern 0:fbeea547d99e -0.15 0.10 london,uk +proposal-modern 0:3c8401edb4cc -0.17 0.10 hello@graphcompose.dev +proposal-modern 0:89674e6f130e -0.20 0.10 +442055551000 +proposal-modern 0:213a61c7aeb6 -0.22 0.10 graphcompose.dev +proposal-modern 0:f890faef907f 0.15 0.11 northwindsystems +proposal-modern 0:577a7fcdaa02 -0.12 0.11 attn:procurement +proposal-modern 0:91eefd794f79 -0.15 0.11 410marketavenue +proposal-modern 0:3daace874084 -0.17 0.11 procurement@northwind.example +proposal-modern 0:5f161c914988 0.19 0.10 scope +proposal-modern 0:9e580657f485 0.03 0.10 discovery,architecture,andarefer +proposal-modern 0:cec9111de36d 0.19 0.10 approach +proposal-modern 0:3215ea3be6d9 0.03 0.10 iterativedeliverywithweeklycheck +proposal-modern 0:94d192b3a326 0.19 0.10 timeline +proposal-modern 0:02195b8e9896 0.03 0.40 phase +proposal-modern 0:caa79af4db67 0.03 0.35 duration +proposal-modern 0:41ffd8b76afc 0.03 0.35 details +proposal-modern 0:fa44132b238e 0.10 0.40 discovery +proposal-modern 0:fa44132b238e#1 0.10 0.40 discovery +proposal-modern 0:b183847fe9f8 0.10 0.35 2weeks +proposal-modern 0:4b20bfb69ca7 0.10 0.35 stakeholderinterviews+audit +proposal-modern 0:44575cf5b285 0.10 0.40 build +proposal-modern 0:44575cf5b285#1 0.10 0.40 build +proposal-modern 0:5a6b4bf425f2 0.10 0.35 6weeks +proposal-modern 0:7a802048127d 0.10 0.35 engine+templatemigration +proposal-modern 0:f9b21c4bda58 0.19 0.10 investment +proposal-modern 0:4a33eacd5fa6 0.03 0.40 item +proposal-modern 0:c9046f7a37ad 0.03 0.35 description +proposal-modern 0:cf38d95c9c6b 0.03 1.42 amount +proposal-modern 0:fe9b6b4f133b 0.10 0.35 workshops+auditgbp6,000 +proposal-modern 0:62e788ae3916 0.10 0.35 engine+templatesgbp24,000 +proposal-modern 0:11239872d178 0.00 0.40 total +proposal-modern 0:1c3065490625 0.00 1.42 gbp30,000 +proposal-modern 0:63feb7230a5d 0.17 0.10 acceptanceterms +proposal-modern 0:35046a9f5675 0.10 9.60 •50%onsignature,50%ondelivery. +proposal-modern 0:f03c1877ea2b 0.10 9.60 •validfor30daysfromthepreparedda +proposal-modern 0:90572e911376 0.02 0.10 thankyouforconsideringgraphcompo proposal-northline 0:5205c2a261bc -0.44 0.05 northline proposal-northline 0:da0daaba4b15 -0.44 0.05 studio proposal-northline 0:ecd1378bc9dc -0.38 1.93 proposal @@ -4065,11 +4066,11 @@ proposal-northline 1:566f68df6dd8 0.05 0.09 finalpayment. proposal-northline 1:06ebb5670fa8 0.33 0.57 ownershipofallfinaldeliverables proposal-northline 1:5312201597c1 0.70 0.09 transferstoasterahealthco.afterf proposal-northline 1:d31e8d77a816 0.30 0.09 paymentisreceived. -proposal-northline 1:c1514c6cdad1 0.06 11.46 acceptance -proposal-northline 1:893663b06769 0.38 11.45 bysigningbelow,youagreetothescop -proposal-northline 1:df16232de5b9 0.37 11.45 acceptedby: -proposal-northline 1:f089d24d7cf3 0.37 11.41 signature: -proposal-northline 1:c74c9cd82f13 0.37 11.42 date: +proposal-northline 1:c1514c6cdad1 0.41 11.46 acceptance +proposal-northline 1:893663b06769 0.73 11.45 bysigningbelow,youagreetothescop +proposal-northline 1:df16232de5b9 0.72 11.45 acceptedby: +proposal-northline 1:f089d24d7cf3 0.72 11.41 signature: +proposal-northline 1:c74c9cd82f13 0.72 11.42 date: proposal-northline 1:026890c58de9 0.01 0.10 northlinestudio|northlinestudio. receipt-modern 0:2b019b5b46da 0.31 0.10 northwindpay receipt-modern 0:a3c304a23bb1 0.30 0.16 transferconfirmation diff --git a/qa/src/test/resources/docx-fidelity/libreoffice-linux.tsv b/qa/src/test/resources/docx-fidelity/libreoffice-linux.tsv index 71d897c42..6fe4a1044 100644 --- a/qa/src/test/resources/docx-fidelity/libreoffice-linux.tsv +++ b/qa/src/test/resources/docx-fidelity/libreoffice-linux.tsv @@ -1,31 +1,31 @@ # libreoffice build 420(Build:2) on linux document engine_pages editor_pages lines matched median p90 over2 cv-blue_banner 2 2 54 52 0.14 0.46 0 -cv-boxed_sections 2 2 58 58 0.35 0.63 0 +cv-boxed_sections 2 2 58 58 0.26 0.37 0 cv-centered_headline 2 2 58 56 0.14 0.32 0 -cv-charcoal_gold 1 1 85 83 0.11 0.34 0 -cv-classic_serif 2 2 57 54 0.06 0.22 0 -cv-compact_mono 1 1 58 58 0.34 0.83 0 +cv-charcoal_gold 1 1 85 83 0.17 0.24 0 +cv-classic_serif 2 2 57 54 0.26 0.31 0 +cv-compact_mono 1 1 58 58 0.24 0.83 0 cv-editorial_blue 2 2 82 82 0.08 0.30 0 -cv-engineering_resume 1 1 57 57 0.60 1.62 0 +cv-engineering_resume 1 1 57 57 0.28 0.41 0 cv-executive 2 2 60 60 0.26 0.50 0 cv-midnight_navy 1 1 86 84 0.28 0.87 0 -cv-minimal_underlined 2 2 59 59 0.72 1.39 0 +cv-minimal_underlined 2 2 59 59 0.35 0.64 0 cv-mint_editorial 2 2 59 59 0.27 0.60 0 -cv-modern_professional 2 2 61 59 0.12 0.41 0 +cv-modern_professional 2 2 61 59 0.23 0.25 0 cv-monogram_sidebar 1 1 53 50 0.25 0.62 0 cv-navy_sidebar 1 1 71 71 0.20 0.45 0 -cv-nordic_clean 1 1 63 58 0.22 0.52 0 +cv-nordic_clean 1 1 63 58 0.25 0.43 0 cv-orange_ops 1 1 108 106 0.26 0.53 0 -cv-panel 1 1 79 74 0.27 0.49 0 +cv-panel 1 1 79 74 0.75 1.21 0 cv-professional_sidebar 1 1 68 64 0.36 0.58 0 cv-serif_headline 1 1 103 103 0.44 0.88 0 cv-sidebar_portrait 1 1 49 49 0.17 0.31 0 cv-slate_orange 1 1 87 86 0.42 1.02 0 cv-teal_pulse 1 1 57 57 0.22 0.63 0 cv-terracotta_rail 1 1 102 102 0.44 0.94 0 -cv-timeline_minimal 2 2 89 86 0.45 0.50 0 -cv-violet_grid 1 1 80 78 0.22 0.44 0 +cv-timeline_minimal 2 2 89 87 0.45 0.49 0 +cv-violet_grid 1 1 80 78 0.26 0.54 0 invoice-classic 1 1 56 56 0.12 0.30 0 invoice-classic_long 2 2 166 166 0.20 0.27 0 invoice-consulting 1 1 92 92 0.67 0.96 0 @@ -33,32 +33,32 @@ invoice-consulting_long 2 2 236 236 0.69 1.04 0 invoice-luma_studio 1 1 97 97 0.12 0.52 2 invoice-luma_studio_long 3 3 192 192 0.20 0.41 2 invoice-merchant 1 1 94 94 0.73 1.91 5 -invoice-metered 1 1 99 99 0.91 10.00 48 +invoice-metered 1 1 99 99 0.91 9.98 48 invoice-modern 1 1 54 54 0.07 0.20 0 invoice-modern_long 2 2 162 162 0.20 0.27 0 -invoice-obsidian 1 1 81 81 1.38 3.35 25 -invoice-payments 1 1 104 104 0.32 5.53 45 -invoice-platform 1 1 111 111 0.39 0.52 0 -invoice-subscription 1 1 81 81 0.28 0.73 0 -invoice-workspace 1 1 90 90 0.17 0.31 0 +invoice-obsidian 1 1 81 81 0.27 3.05 15 +invoice-payments 1 1 104 104 0.32 5.63 45 +invoice-platform 1 1 111 111 0.42 0.52 0 +invoice-subscription 1 1 81 81 0.54 0.67 0 +invoice-workspace 1 1 90 90 0.28 0.67 0 letter-blue_banner 1 1 10 10 0.42 0.46 0 -letter-boxed_sections 1 1 10 10 0.46 0.70 0 +letter-boxed_sections 1 1 10 10 0.29 0.33 0 letter-centered_headline 1 1 11 11 0.13 0.25 0 letter-classic_serif 1 1 10 10 0.13 0.19 0 letter-compact_mono 1 1 10 8 0.24 0.35 0 letter-editorial_blue 1 1 12 12 0.16 0.22 0 -letter-engineering_resume 1 1 15 15 1.40 1.66 0 +letter-engineering_resume 1 1 15 15 0.19 0.41 0 letter-executive 1 1 12 12 0.18 0.30 0 letter-mint-editorial-letter 1 1 10 10 0.29 0.29 0 -letter-modern_professional 1 1 12 12 0.43 0.43 0 +letter-modern_professional 1 1 12 12 0.08 0.22 0 letter-monogram_sidebar 1 1 12 12 0.23 0.37 0 letter-nordic_clean 1 1 15 15 0.16 0.38 0 -letter-panel 1 1 13 13 0.15 0.21 0 +letter-panel 1 1 13 13 0.13 0.17 0 letter-sidebar_portrait 1 1 12 12 0.43 0.51 0 letter-timeline_minimal 1 1 15 15 0.33 0.53 0 -proposal-editorial 2 2 132 129 44.55 45.38 72 +proposal-editorial 2 2 132 129 44.49 45.38 72 proposal-indigo 1 1 72 70 0.26 0.65 0 -proposal-modern 1 1 44 44 0.50 0.75 0 -proposal-northline 2 2 132 132 0.27 0.57 0 +proposal-modern 1 1 44 44 0.10 0.20 0 +proposal-northline 2 2 132 132 0.27 0.67 0 receipt-modern 1 1 57 57 0.26 0.29 0 rota-cobalt 1 1 154 151 0.23 0.79 0