{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"codehealth","informationUri":"https://codehealth.canine.dev","rules":[{"id":"D1","name":"Cyclomatic Complexity","shortDescription":{"text":"Cyclomatic Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/D1"},{"id":"D2","name":"Cognitive Complexity","shortDescription":{"text":"Cognitive Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/D2"},{"id":"D3","name":"God Classes","shortDescription":{"text":"God Classes"},"helpUri":"https://codehealth.canine.dev/dimensions/D3"},{"id":"D4","name":"Code Duplication","shortDescription":{"text":"Code Duplication"},"helpUri":"https://codehealth.canine.dev/dimensions/D4"},{"id":"D5","name":"Coupling","shortDescription":{"text":"Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D5"},{"id":"D6","name":"Cohesion (LCOM4)","shortDescription":{"text":"Cohesion (LCOM4)"},"helpUri":"https://codehealth.canine.dev/dimensions/D6"},{"id":"D7","name":"Architectural Integrity","shortDescription":{"text":"Architectural Integrity"},"helpUri":"https://codehealth.canine.dev/dimensions/D7"},{"id":"D9","name":"Test Distribution","shortDescription":{"text":"Test Distribution"},"helpUri":"https://codehealth.canine.dev/dimensions/D9"},{"id":"D10","name":"Test Quality","shortDescription":{"text":"Test Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D10"},{"id":"D12","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/D12"},{"id":"D13","name":"Secret Scanning","shortDescription":{"text":"Secret Scanning"},"helpUri":"https://codehealth.canine.dev/dimensions/D13","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"],"owasp":"A07:2025"}},{"id":"D14","name":"License Compliance","shortDescription":{"text":"License Compliance"},"helpUri":"https://codehealth.canine.dev/dimensions/D14"},{"id":"D15","name":"Churn \u00D7 Complexity Hotspots","shortDescription":{"text":"Churn \u00D7 Complexity Hotspots"},"helpUri":"https://codehealth.canine.dev/dimensions/D15"},{"id":"D16","name":"Bus Factor","shortDescription":{"text":"Bus Factor"},"helpUri":"https://codehealth.canine.dev/dimensions/D16"},{"id":"D17","name":"Explicit Debt","shortDescription":{"text":"Explicit Debt"},"helpUri":"https://codehealth.canine.dev/dimensions/D17"},{"id":"D19","name":"Documentation Quality","shortDescription":{"text":"Documentation Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D19"},{"id":"D20","name":"ADR Quality","shortDescription":{"text":"ADR Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D20"},{"id":"D21","name":"Naming Consistency","shortDescription":{"text":"Naming Consistency"},"helpUri":"https://codehealth.canine.dev/dimensions/D21"},{"id":"D23","name":"Boundary Type-Coupling","shortDescription":{"text":"Boundary Type-Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D23"},{"id":"D25","name":"ADR Conformance","shortDescription":{"text":"ADR Conformance"},"helpUri":"https://codehealth.canine.dev/dimensions/D25"},{"id":"D26","name":"Project Cohesion","shortDescription":{"text":"Project Cohesion"},"helpUri":"https://codehealth.canine.dev/dimensions/D26"},{"id":"D28","name":"Secrets (history)","shortDescription":{"text":"Secrets (history)"},"helpUri":"https://codehealth.canine.dev/dimensions/D28","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"],"owasp":"A07:2025"}},{"id":"D29","name":"Static Analysis (SAST)","shortDescription":{"text":"Static Analysis (SAST)"},"helpUri":"https://codehealth.canine.dev/dimensions/D29","relationships":[{"target":{"id":"CWE-79","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-94","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-77","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-79","CWE-89","CWE-78","CWE-94","CWE-77"],"owasp":"A05:2025"}},{"id":"D30","name":"Dependency Vulnerabilities","shortDescription":{"text":"Dependency Vulnerabilities"},"helpUri":"https://codehealth.canine.dev/dimensions/D30","relationships":[{"target":{"id":"CWE-1395","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-937","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1395","CWE-937"],"owasp":"A03:2025"}},{"id":"D31","name":"IaC \u0026 Container Security","shortDescription":{"text":"IaC \u0026 Container Security"},"helpUri":"https://codehealth.canine.dev/dimensions/D31","relationships":[{"target":{"id":"CWE-1032","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-732","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-16","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1032","CWE-732","CWE-16"],"owasp":"A02:2025"}},{"id":"D34","name":"Knowledge Freshness","shortDescription":{"text":"Knowledge Freshness"},"helpUri":"https://codehealth.canine.dev/dimensions/D34"},{"id":"D35","name":"Change Coupling","shortDescription":{"text":"Change Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D35"},{"id":"D36","name":"Supply-chain Provenance \u0026 Signing","shortDescription":{"text":"Supply-chain Provenance \u0026 Signing"},"helpUri":"https://codehealth.canine.dev/dimensions/D36","relationships":[{"target":{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1357","CWE-494"],"owasp":"A03:2025"}},{"id":"D37","name":"Vulnerability-disclosure Policy","shortDescription":{"text":"Vulnerability-disclosure Policy"},"helpUri":"https://codehealth.canine.dev/dimensions/D37","relationships":[{"target":{"id":"CWE-1059","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1059"],"owasp":"A02:2025"}},{"id":"D43","name":"Malicious Dependencies","shortDescription":{"text":"Malicious Dependencies"},"helpUri":"https://codehealth.canine.dev/dimensions/D43","relationships":[{"target":{"id":"CWE-506","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-506"],"owasp":"A08:2025"}},{"id":"D44","name":"Platform End-of-Life","shortDescription":{"text":"Platform End-of-Life"},"helpUri":"https://codehealth.canine.dev/dimensions/D44"},{"id":"AC1","name":"Text alternatives","shortDescription":{"text":"Text alternatives"},"helpUri":"https://codehealth.canine.dev/dimensions/AC1"},{"id":"AC2","name":"Forms \u0026 labels","shortDescription":{"text":"Forms \u0026 labels"},"helpUri":"https://codehealth.canine.dev/dimensions/AC2"},{"id":"AC3","name":"Page structure","shortDescription":{"text":"Page structure"},"helpUri":"https://codehealth.canine.dev/dimensions/AC3"},{"id":"AC4","name":"Keyboard semantics","shortDescription":{"text":"Keyboard semantics"},"helpUri":"https://codehealth.canine.dev/dimensions/AC4"},{"id":"AC5","name":"ARIA correctness","shortDescription":{"text":"ARIA correctness"},"helpUri":"https://codehealth.canine.dev/dimensions/AC5"},{"id":"AC6","name":"Visual \u0026 motion safety","shortDescription":{"text":"Visual \u0026 motion safety"},"helpUri":"https://codehealth.canine.dev/dimensions/AC6"},{"id":"AC7","name":"A11y enforcement","shortDescription":{"text":"A11y enforcement"},"helpUri":"https://codehealth.canine.dev/dimensions/AC7"},{"id":"AX10","name":"Code composition","shortDescription":{"text":"Code composition"},"helpUri":"https://codehealth.canine.dev/dimensions/AX10"},{"id":"AX3","name":"Project dependency cycles","shortDescription":{"text":"Project dependency cycles"},"helpUri":"https://codehealth.canine.dev/dimensions/AX3"},{"id":"AX4","name":"Dependency direction","shortDescription":{"text":"Dependency direction"},"helpUri":"https://codehealth.canine.dev/dimensions/AX4"},{"id":"AX6","name":"Interface segregation","shortDescription":{"text":"Interface segregation"},"helpUri":"https://codehealth.canine.dev/dimensions/AX6"},{"id":"AXB2","name":"Runtime readiness","shortDescription":{"text":"Runtime readiness"},"helpUri":"https://codehealth.canine.dev/dimensions/AXB2"},{"id":"C1","name":"Data Protection","shortDescription":{"text":"Data Protection"},"helpUri":"https://codehealth.canine.dev/dimensions/C1"},{"id":"C2","name":"Access Controls","shortDescription":{"text":"Access Controls"},"helpUri":"https://codehealth.canine.dev/dimensions/C2"},{"id":"C4","name":"Data Retention","shortDescription":{"text":"Data Retention"},"helpUri":"https://codehealth.canine.dev/dimensions/C4"},{"id":"DM1","name":"Aggregate boundaries","shortDescription":{"text":"Aggregate boundaries"},"helpUri":"https://codehealth.canine.dev/dimensions/DM1"},{"id":"DM11","name":"Constructible invalid state","shortDescription":{"text":"Constructible invalid state"},"helpUri":"https://codehealth.canine.dev/dimensions/DM11"},{"id":"DM4","name":"Rich vs anemic model","shortDescription":{"text":"Rich vs anemic model"},"helpUri":"https://codehealth.canine.dev/dimensions/DM4"},{"id":"DM5","name":"Encapsulated state","shortDescription":{"text":"Encapsulated state"},"helpUri":"https://codehealth.canine.dev/dimensions/DM5"},{"id":"DM8","name":"Value-object opportunities","shortDescription":{"text":"Value-object opportunities"},"helpUri":"https://codehealth.canine.dev/dimensions/DM8"},{"id":"DM9","name":"Scattered domain decisions","shortDescription":{"text":"Scattered domain decisions"},"helpUri":"https://codehealth.canine.dev/dimensions/DM9"},{"id":"ED5","name":"Idempotency","shortDescription":{"text":"Idempotency"},"helpUri":"https://codehealth.canine.dev/dimensions/ED5"},{"id":"M1","name":"Documentation (README)","shortDescription":{"text":"Documentation (README)"},"helpUri":"https://codehealth.canine.dev/dimensions/M1"},{"id":"M2","name":"Architecture documentation","shortDescription":{"text":"Architecture documentation"},"helpUri":"https://codehealth.canine.dev/dimensions/M2"},{"id":"M3","name":"Folder \u0026 project structure","shortDescription":{"text":"Folder \u0026 project structure"},"helpUri":"https://codehealth.canine.dev/dimensions/M3"},{"id":"M4","name":"Documentation accuracy","shortDescription":{"text":"Documentation accuracy"},"helpUri":"https://codehealth.canine.dev/dimensions/M4"},{"id":"P1","name":"CI/CD gates","shortDescription":{"text":"CI/CD gates"},"helpUri":"https://codehealth.canine.dev/dimensions/P1"},{"id":"P12","name":"CI test-gate honesty","shortDescription":{"text":"CI test-gate honesty"},"helpUri":"https://codehealth.canine.dev/dimensions/P12"},{"id":"P2","name":"Observability","shortDescription":{"text":"Observability"},"helpUri":"https://codehealth.canine.dev/dimensions/P2"},{"id":"P3","name":"Security \u0026 performance tooling","shortDescription":{"text":"Security \u0026 performance tooling"},"helpUri":"https://codehealth.canine.dev/dimensions/P3"},{"id":"P4","name":"Deployment \u0026 Rollback","shortDescription":{"text":"Deployment \u0026 Rollback"},"helpUri":"https://codehealth.canine.dev/dimensions/P4"},{"id":"P5","name":"DR \u0026 Backup","shortDescription":{"text":"DR \u0026 Backup"},"helpUri":"https://codehealth.canine.dev/dimensions/P5"},{"id":"P6","name":"Release Hygiene","shortDescription":{"text":"Release Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/P6"},{"id":"P7","name":"Outbound HTTP resilience","shortDescription":{"text":"Outbound HTTP resilience"},"helpUri":"https://codehealth.canine.dev/dimensions/P7"},{"id":"P8","name":"Schema migrations","shortDescription":{"text":"Schema migrations"},"helpUri":"https://codehealth.canine.dev/dimensions/P8"},{"id":"PF3","name":"Async \u0026 latency hygiene","shortDescription":{"text":"Async \u0026 latency hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/PF3"},{"id":"R1","name":"Type Safety","shortDescription":{"text":"Type Safety"},"helpUri":"https://codehealth.canine.dev/dimensions/R1"},{"id":"R10","name":"Code Duplication","shortDescription":{"text":"Code Duplication"},"helpUri":"https://codehealth.canine.dev/dimensions/R10"},{"id":"R11","name":"Import Boundaries","shortDescription":{"text":"Import Boundaries"},"helpUri":"https://codehealth.canine.dev/dimensions/R11"},{"id":"R2","name":"Cyclomatic Complexity","shortDescription":{"text":"Cyclomatic Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/R2"},{"id":"R3","name":"Large Files","shortDescription":{"text":"Large Files"},"helpUri":"https://codehealth.canine.dev/dimensions/R3"},{"id":"R4","name":"Test Coverage","shortDescription":{"text":"Test Coverage"},"helpUri":"https://codehealth.canine.dev/dimensions/R4"},{"id":"R5","name":"Dependency Freshness","shortDescription":{"text":"Dependency Freshness"},"helpUri":"https://codehealth.canine.dev/dimensions/R5"},{"id":"R6","name":"Tooling","shortDescription":{"text":"Tooling"},"helpUri":"https://codehealth.canine.dev/dimensions/R6"},{"id":"R7","name":"Dead Code","shortDescription":{"text":"Dead Code"},"helpUri":"https://codehealth.canine.dev/dimensions/R7"},{"id":"R8","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/R8"},{"id":"R9","name":"Circular Imports","shortDescription":{"text":"Circular Imports"},"helpUri":"https://codehealth.canine.dev/dimensions/R9"},{"id":"S1","name":"Web-Security Posture","shortDescription":{"text":"Web-Security Posture"},"helpUri":"https://codehealth.canine.dev/dimensions/S1"},{"id":"SC1","name":"Supply-chain hygiene","shortDescription":{"text":"Supply-chain hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/SC1"},{"id":"X1","name":"Async correctness","shortDescription":{"text":"Async correctness"},"helpUri":"https://codehealth.canine.dev/dimensions/X1"},{"id":"X10","name":"Duplicated predicate","shortDescription":{"text":"Duplicated predicate"},"helpUri":"https://codehealth.canine.dev/dimensions/X10"},{"id":"X12","name":"Unreachable branch","shortDescription":{"text":"Unreachable branch"},"helpUri":"https://codehealth.canine.dev/dimensions/X12"},{"id":"X13","name":"Undrained process stream","shortDescription":{"text":"Undrained process stream"},"helpUri":"https://codehealth.canine.dev/dimensions/X13"},{"id":"X14","name":"Bypassable address classification","shortDescription":{"text":"Bypassable address classification"},"helpUri":"https://codehealth.canine.dev/dimensions/X14"},{"id":"X15","name":"Unvalidated length from an untrusted reader","shortDescription":{"text":"Unvalidated length from an untrusted reader"},"helpUri":"https://codehealth.canine.dev/dimensions/X15"},{"id":"X16","name":"Unfloored truncation loop","shortDescription":{"text":"Unfloored truncation loop"},"helpUri":"https://codehealth.canine.dev/dimensions/X16"},{"id":"X17","name":"Uncapped recursion over a caller-supplied document","shortDescription":{"text":"Uncapped recursion over a caller-supplied document"},"helpUri":"https://codehealth.canine.dev/dimensions/X17"},{"id":"X18","name":"Disposal-pattern correctness","shortDescription":{"text":"Disposal-pattern correctness"},"helpUri":"https://codehealth.canine.dev/dimensions/X18"},{"id":"X19","name":"Unrestored process-global state","shortDescription":{"text":"Unrestored process-global state"},"helpUri":"https://codehealth.canine.dev/dimensions/X19"},{"id":"X2","name":"Cancellation propagation","shortDescription":{"text":"Cancellation propagation"},"helpUri":"https://codehealth.canine.dev/dimensions/X2"},{"id":"X20","name":"Mistyped argument guard","shortDescription":{"text":"Mistyped argument guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X20"},{"id":"X21","name":"Side-effecting pattern guard","shortDescription":{"text":"Side-effecting pattern guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X21"},{"id":"X22","name":"Contradicted release guard","shortDescription":{"text":"Contradicted release guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X22"},{"id":"X23","name":"Unguarded diagnostic materialisation","shortDescription":{"text":"Unguarded diagnostic materialisation"},"helpUri":"https://codehealth.canine.dev/dimensions/X23"},{"id":"X24","name":"Document value interpolated into markup unescaped","shortDescription":{"text":"Document value interpolated into markup unescaped"},"helpUri":"https://codehealth.canine.dev/dimensions/X24"},{"id":"X25","name":"Inert configuration knob","shortDescription":{"text":"Inert configuration knob"},"helpUri":"https://codehealth.canine.dev/dimensions/X25"},{"id":"X26","name":"Unsynchronised callback handoff","shortDescription":{"text":"Unsynchronised callback handoff"},"helpUri":"https://codehealth.canine.dev/dimensions/X26"},{"id":"X28","name":"Index access outside its own emptiness guard","shortDescription":{"text":"Index access outside its own emptiness guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X28"},{"id":"X29","name":"Per-element action decided by a fixed element","shortDescription":{"text":"Per-element action decided by a fixed element"},"helpUri":"https://codehealth.canine.dev/dimensions/X29"},{"id":"X3","name":"Exception handling","shortDescription":{"text":"Exception handling"},"helpUri":"https://codehealth.canine.dev/dimensions/X3"},{"id":"X30","name":"Support guard that admits what it rejects","shortDescription":{"text":"Support guard that admits what it rejects"},"helpUri":"https://codehealth.canine.dev/dimensions/X30"},{"id":"X32","name":"Type resolved by simple name across every loaded assembly","shortDescription":{"text":"Type resolved by simple name across every loaded assembly"},"helpUri":"https://codehealth.canine.dev/dimensions/X32"},{"id":"X4","name":"Structured logging","shortDescription":{"text":"Structured logging"},"helpUri":"https://codehealth.canine.dev/dimensions/X4"},{"id":"X5","name":"Nullable reference types","shortDescription":{"text":"Nullable reference types"},"helpUri":"https://codehealth.canine.dev/dimensions/X5"},{"id":"X6","name":"Hand-rolled structured-format parsing","shortDescription":{"text":"Hand-rolled structured-format parsing"},"helpUri":"https://codehealth.canine.dev/dimensions/X6"},{"id":"X7","name":"Silent fallback defaults","shortDescription":{"text":"Silent fallback defaults"},"helpUri":"https://codehealth.canine.dev/dimensions/X7"},{"id":"X9","name":"Subsumed condition operand","shortDescription":{"text":"Subsumed condition operand"},"helpUri":"https://codehealth.canine.dev/dimensions/X9"}]}},"results":[{"ruleId":"D1","level":"warning","message":{"text":"Extractor.createFromFile (cyclomatic 67): Extractor.createFromFile has cyclomatic complexity 67 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Metadata/Extractor.php"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e5c414c76f976da570c749e4abb36ae81e9b642e2fc15e8095c4478646def26"}},{"ruleId":"D1","level":"warning","message":{"text":"useSpotlightGalleryActions.useSpotlightGalleryActions (cyclomatic 42): useSpotlightGalleryActions.useSpotlightGalleryActions has cyclomatic complexity 42 (threshold 15). Most of this is not in the body itself: 1 of the 42 points is its own statement and the rest belongs to 4 function literals inside it that branch (lines 73, 47, 61, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/spotlight/useSpotlightGalleryActions.ts"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"40b87ca8e2c8f73bb239b58e2582b17ff6dce77f127669da83fd30ee8087cb7b"}},{"ruleId":"D1","level":"warning","message":{"text":"Configs.sanity (cyclomatic 41): Configs.sanity has cyclomatic complexity 41 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Configs.php"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"4515374ef197d33be1dd79c47215aecc8b4fd45dc7d9d0520cfe3031e2218844"}},{"ruleId":"D1","level":"warning","message":{"text":"ExifLens.handle (cyclomatic 36): ExifLens.handle has cyclomatic complexity 36 (threshold 15). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/ImageProcessing/ExifLens.php"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"771bf9aae4d48410e23cec5d02f22412302340b7f88b489b14e184f154147b79"}},{"ruleId":"D1","level":"warning","message":{"text":"QueryPhotoDetails.buildResource (cyclomatic 35): QueryPhotoDetails.buildResource has cyclomatic complexity 35 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoDetails.php"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"453af5fab009e83b4a756a485c36b6f23d5a2e104f4b74f021a939d750c79a5f"}},{"ruleId":"D1","level":"warning","message":{"text":"Ghostbuster.handle (cyclomatic 31): Ghostbuster.handle has cyclomatic complexity 31 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/Ghostbuster.php"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbeb09cb9898b9c28ec191a54fb503f12b99b3fc464b89ac290ee5531eed3def"}},{"ruleId":"D1","level":"warning","message":{"text":"BulkEditAlbumsAction.do (cyclomatic 29): BulkEditAlbumsAction.do has cyclomatic complexity 29 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Admin/BulkEditAlbumsAction.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"a35bc94aedf83a9d15bfea1cb5e884f62ac2f9c89ac4387432e3d3ed2f16814d"}},{"ruleId":"D1","level":"warning","message":{"text":"config.parseDataAttributes (cyclomatic 28): config.parseDataAttributes has cyclomatic complexity 28 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/config.ts"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"1143be3ef106fc3b345d4574e4433a6d595149223a6061a8b2b40ab122a8bff3"}},{"ruleId":"D1","level":"warning","message":{"text":"config.validateConfig (cyclomatic 27): config.validateConfig has cyclomatic complexity 27 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/config.ts"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef7d0dbbbc38d6dff85bb6f625ea56b850da5b0195593b82a2c120e72fb9385d"}},{"ruleId":"D1","level":"warning","message":{"text":"sprintf.parse (cyclomatic 26): sprintf.parse has cyclomatic complexity 26 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/utils/sprintf.ts"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d5746566db5599a57d22c29527e164d534534b78aee642a8e397d9f42b2a71e"}},{"ruleId":"D1","level":"warning","message":{"text":"IniSettingsCheck.handle (cyclomatic 25): IniSettingsCheck.handle has cyclomatic complexity 25 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Diagnostics/Pipes/Checks/IniSettingsCheck.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2fd100248b23553fe4843124d96894ff9dc5168c4940a2c914630f06242647b"}},{"ruleId":"D1","level":"warning","message":{"text":"SecurityAdvisoriesService.getMatchingAdvisories (cyclomatic 24): SecurityAdvisoriesService.getMatchingAdvisories has cyclomatic complexity 24 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/SecurityAdvisoriesService.php"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"d60fb08a55d1f5741e918ded5edca2d5d2fbf2e1cfada0c919050912da93da1c"}},{"ruleId":"D1","level":"warning","message":{"text":"quickNaming.decideKey (cyclomatic 24): quickNaming.decideKey has cyclomatic complexity 24 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/quickNaming.ts"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"dce00291be39d3ea65baa44e8ad9d585cb773b3a3243e671ee9bda1636cb44ed"}},{"ruleId":"D1","level":"warning","message":{"text":"BasicPermissionCheck.checkDirectoryPermissionsRecursively (cyclomatic 23): BasicPermissionCheck.checkDirectoryPermissionsRecursively has cyclomatic complexity 23 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Diagnostics/Pipes/Checks/BasicPermissionCheck.php"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"93e0fb59628eb73ccba629a121beac32196d110570c987ae38af5b3f5d644bb6"}},{"ruleId":"D1","level":"warning","message":{"text":"HydrateMetadata.handle (cyclomatic 23): HydrateMetadata.handle has cyclomatic complexity 23 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/Pipes/Shared/HydrateMetadata.php"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e2fa1d923de4a92414602b6bb5ca5343f078cc9948bcbeee30b9586698a6f59"}},{"ruleId":"D1","level":"warning","message":{"text":"leftMenu.useLeftMenu.items (cyclomatic 23): leftMenu.useLeftMenu.items has cyclomatic complexity 23 (threshold 15). Of this number, 22 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef049bd28ebd6768c4e34c350af658a6566d8c5e16f6fce65d7dde9d60d21c0b"}},{"ruleId":"D1","level":"warning","message":{"text":"sprintf.convertNumber (cyclomatic 21): sprintf.convertNumber has cyclomatic complexity 21 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/utils/sprintf.ts"},"region":{"startLine":298}}}],"partialFingerprints":{"codehealthFindingId/v1":"2642ea42b7b95d13a3397c20a854e4d28e56b5eba7b4e5af9bdf5f4df309d435"}},{"ruleId":"D1","level":"warning","message":{"text":"QueryPhotoRatios.buildResource (cyclomatic 20): QueryPhotoRatios.buildResource has cyclomatic complexity 20 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"74395dfaf24af3c56c4bcf9a476be14372f38136c48168be291fc2ee3d9971bb"}},{"ruleId":"D1","level":"warning","message":{"text":"QuerySearchPhotos.buildResource (cyclomatic 20): QuerySearchPhotos.buildResource has cyclomatic complexity 20 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Search/StructOfArrays/QuerySearchPhotos.php"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b6387f8e17210ad1d9cba601a04764a2f32b7f3d6e68bdd74c01037c4a259dc"}},{"ruleId":"D1","level":"warning","message":{"text":"AlbumConfig.__construct (cyclomatic 20): AlbumConfig.__construct has cyclomatic complexity 20 (threshold 15). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/GalleryConfigs/AlbumConfig.php"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"32790fc29cbcb66e6cafcb6e8a008f22ada28a7c0ef8084482d547df833f2f4c"}},{"ruleId":"D1","level":"warning","message":{"text":"albumStatistics.useAlbumsStatistics.getStatistics (cyclomatic 20): albumStatistics.useAlbumsStatistics.getStatistics has cyclomatic complexity 20 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/albumStatistics.ts"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5535bf3b187770714cc42b96c404150d9bcb16846bc4546d74bcc9b64b5ac26"}},{"ruleId":"D1","level":"warning","message":{"text":"dragAndSelect.useDragAndSelect.getAlbumBoxesV3 (cyclomatic 20): dragAndSelect.useDragAndSelect.getAlbumBoxesV3 has cyclomatic complexity 20 (threshold 15). Most of this is not in the body itself: 1 of the 20 points is its own statement and the rest belongs to 3 function literals inside it that branch (lines 346, 404, 419). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/dragAndSelect.ts"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"256bafc5ff0d01302b86a8b41089ed87cd65be3f974a9a4c2b2254861bfcaa4d"}},{"ruleId":"D1","level":"warning","message":{"text":"useSearchTokenAssembler.parseTokens (cyclomatic 20): useSearchTokenAssembler.parseTokens has cyclomatic complexity 20 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useSearchTokenAssembler.ts"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0bfda652384814aaf683a2815eebaf0b90a57296c6732aa8a000067a8827374"}},{"ruleId":"D1","level":"warning","message":{"text":"useAdminTiles.useAdminTiles (cyclomatic 20): useAdminTiles.useAdminTiles has cyclomatic complexity 20 (threshold 15). Most of this is not in the body itself: 1 of the 20 points is its own statement and the rest belongs to 10 function literals inside it that branch (lines 110, 206, 163, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useAdminTiles.ts"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"971170bd69a8897521e2ad267232a3bcc3758a7f4f725d1fea198511e55227ab"}},{"ruleId":"D1","level":"warning","message":{"text":"SafeZipExtractor.extract (cyclomatic 19): SafeZipExtractor.extract has cyclomatic complexity 19 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Zip/SafeZipExtractor.php"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"e78f123c1f127f7ec4fc97e8469e3bb4deeae2bb22d57d532d17a28c2bd33de3"}},{"ruleId":"D1","level":"warning","message":{"text":"useSearchTokenAssembler.assembleTokens (cyclomatic 19): useSearchTokenAssembler.assembleTokens has cyclomatic complexity 19 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useSearchTokenAssembler.ts"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"780dc15e51658889b61fff7538c27fc487f7eab64483d9026ac4b39393e62ad1"}},{"ruleId":"D1","level":"warning","message":{"text":"BulkAlbumPatchData.fromValidated (cyclomatic 18): BulkAlbumPatchData.fromValidated has cyclomatic complexity 18 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/DTO/BulkAlbumPatchData.php"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e965d10ea52156370f30b07f20ab599d52d1ad96d065371c96c87b057481baa"}},{"ruleId":"D1","level":"warning","message":{"text":"BatchFaceRequest.withValidator (cyclomatic 18): BatchFaceRequest.withValidator has cyclomatic complexity 18 (threshold 15). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Face/BatchFaceRequest.php"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"69f54b421b1d10b084345a6acb29cc30ea97fed35889c1561adb009781c972a0"}},{"ruleId":"D1","level":"warning","message":{"text":"InitConfig.__construct (cyclomatic 18): InitConfig.__construct has cyclomatic complexity 18 (threshold 15). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/GalleryConfigs/InitConfig.php"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa96b8f343def084584198378ad4b4dcf9329c0693e06f953f34e7e464bfc08c"}},{"ruleId":"D1","level":"warning","message":{"text":"contextMenu.useContextMenu.photoMenu (cyclomatic 17): contextMenu.useContextMenu.photoMenu has cyclomatic complexity 17 (threshold 15). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"428ed024539a6782566a32ab95ee4ad33dd3fbc5c163810d93915e668ab51d9a"}},{"ruleId":"D1","level":"warning","message":{"text":"contextMenu.useContextMenu.photoMenu (cyclomatic 17): contextMenu.useContextMenu.photoMenu has cyclomatic complexity 17 (threshold 15). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/contextMenu.ts"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc8c19001430af1deb2810cb20ee8570714d4e2500fc8920246edf6fff0bcdd3"}},{"ruleId":"D1","level":"warning","message":{"text":"ExtractMotionPhotos.handle (cyclomatic 16): ExtractMotionPhotos.handle has cyclomatic complexity 16 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/ImageProcessing/ExtractMotionPhotos.php"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"6067066c925fabb53bd28c5f3e741c192503a573c7e2d0024b4996ff8409ad8e"}},{"ruleId":"D1","level":"warning","message":{"text":"Order.canProcessPayment (cyclomatic 16): Order.canProcessPayment has cyclomatic complexity 16 (threshold 15). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Order.php"},"region":{"startLine":303}}}],"partialFingerprints":{"codehealthFindingId/v1":"2612021624e89c5f5035d344a8817a34bca6067fa02994a9cede6199a34c81c2"}},{"ruleId":"D1","level":"warning","message":{"text":"buyMeActions.useBuyMeActions.toggleBuyMe (cyclomatic 16): buyMeActions.useBuyMeActions.toggleBuyMe has cyclomatic complexity 16 (threshold 15). Of this number, 15 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/buyMeActions.ts"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4757fe8c742e17ba59c137730c955078f898b5ed863b423461b7341fb956012"}},{"ruleId":"D2","level":"warning","message":{"text":"Extractor.createFromFile (cognitive 84): Extractor.createFromFile has cognitive complexity 84 (threshold 15). Drivers by points: if/else 25 (36 pts), ternaries 23 (28 pts), boolean chains 12, error handling 4 (7 pts), match/switch 1 (nesting depth added 19). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Metadata/Extractor.php"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f321621901e01ba2e5b849ac1a03cbe338e6803957351d5a520507328153d2e"}},{"ruleId":"D2","level":"warning","message":{"text":"Ghostbuster.handle (cognitive 56): Ghostbuster.handle has cognitive complexity 56 (threshold 15). Drivers by points: if/else 20 (34 pts), loops 4 (11 pts), boolean chains 5, ternaries 3 (5 pts), error handling 1 (nesting depth added 23). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/Ghostbuster.php"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac75ebcee9878c885599f6a241d8193e7115e93f95a0460a97756d313ddb50ac"}},{"ruleId":"D2","level":"warning","message":{"text":"ExifLens.handle (cognitive 46): ExifLens.handle has cognitive complexity 46 (threshold 15). Drivers by points: boolean chains 21, if/else 11 (20 pts), error handling 3 (4 pts), loops 1 (nesting depth added 10). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/ImageProcessing/ExifLens.php"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc1cd9729220c4c12ec980fee14267a26f7b8718802f3702a30056da542d1f35"}},{"ruleId":"D2","level":"warning","message":{"text":"Configs.sanity (cognitive 46): Configs.sanity has cognitive complexity 46 (threshold 15). Drivers by points: if/else 15 (30 pts), boolean chains 7, error handling 3 (6 pts), loops 1 (2 pts), match/switch 1 (nesting depth added 19). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Configs.php"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"50fcec208225d4eb92cc0a344580afe060758e8746f208fdd08ee2b8c2bd0143"}},{"ruleId":"D2","level":"warning","message":{"text":"sprintf.parse (cognitive 45): sprintf.parse has cognitive complexity 45 (threshold 15). Drivers by points: if/else 15 (29 pts), loops 4 (9 pts), boolean chains 5, ternaries 1 (2 pts) (nesting depth added 20). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/utils/sprintf.ts"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"01bc65e6c115a6494550e4636b19e8355cebad6a68bb77589ead81592a943699"}},{"ruleId":"D2","level":"warning","message":{"text":"BulkEditAlbumsAction.do (cognitive 42): BulkEditAlbumsAction.do has cognitive complexity 42 (threshold 15). Drivers by points: ternaries 7 (20 pts), if/else 16, boolean chains 4, loops 1 (2 pts) (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Admin/BulkEditAlbumsAction.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"0679cb9f1b8b7efcdc1629b3411643ac5d50635ba181bb9e7205939e7e8488d3"}},{"ruleId":"D2","level":"warning","message":{"text":"QueryPhotoDetails.buildResource (cognitive 40): QueryPhotoDetails.buildResource has cognitive complexity 40 (threshold 15). Drivers by points: ternaries 17 (22 pts), boolean chains 9, if/else 3 (6 pts), match/switch 1 (2 pts), loops 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoDetails.php"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ba6cd121963d6794dfbf402c34e78bd33b40733c9747918ecd5dd9728d6fb53"}},{"ruleId":"D2","level":"warning","message":{"text":"SecurityAdvisoriesService.getMatchingAdvisories (cognitive 40): SecurityAdvisoriesService.getMatchingAdvisories has cognitive complexity 40 (threshold 15). Drivers by points: if/else 15 (28 pts), boolean chains 4, ternaries 1 (4 pts), loops 2 (3 pts), error handling 1 (nesting depth added 17). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/SecurityAdvisoriesService.php"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"43c6accc0340f68b1974f14d6c8691cbff2f9374c891a7c2890598b88745bea7"}},{"ruleId":"D2","level":"warning","message":{"text":"QueryPhotoRatios.buildResource (cognitive 34): QueryPhotoRatios.buildResource has cognitive complexity 34 (threshold 15). Drivers by points: ternaries 9 (19 pts), if/else 4 (9 pts), boolean chains 5, loops 1 (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"656154481c2f248b67860ebf979caa52cae427d5cfad5245b646ea07287cee78"}},{"ruleId":"D2","level":"warning","message":{"text":"QuerySearchPhotos.buildResource (cognitive 34): QuerySearchPhotos.buildResource has cognitive complexity 34 (threshold 15). Drivers by points: ternaries 9 (19 pts), if/else 4 (9 pts), boolean chains 5, loops 1 (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Search/StructOfArrays/QuerySearchPhotos.php"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"b915d5b681c741d0a9de5710687ae6a5e947b9607a0d026ad4dfd822dd491d76"}},{"ruleId":"D2","level":"warning","message":{"text":"config.parseDataAttributes (cognitive 34): config.parseDataAttributes has cognitive complexity 34 (threshold 15). Drivers by points: if/else 24 (30 pts), boolean chains 4 (nesting depth added 6). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/config.ts"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"85f09e8e692f490296188b4f58b3353002c2dfff93baef24a8434833af94b45b"}},{"ruleId":"D2","level":"warning","message":{"text":"SafeZipExtractor.extract (cognitive 33): SafeZipExtractor.extract has cognitive complexity 33 (threshold 15). Drivers by points: if/else 13 (25 pts), error handling 2 (4 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Zip/SafeZipExtractor.php"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"d68108b265a15660c917cdd8c03c3d770899d9adf473457322632362c3e4d2b9"}},{"ruleId":"D2","level":"warning","message":{"text":"useSpotlightGalleryActions.useSpotlightGalleryActions (cognitive 29): useSpotlightGalleryActions.useSpotlightGalleryActions has cognitive complexity 29 (threshold 15). Drivers by points: boolean chains 17, if/else 12. None of this is in the body itself: all 29 points belong to 4 function literals inside it that branch (lines 73, 47, 61, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/spotlight/useSpotlightGalleryActions.ts"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"682a2ad17287c0dca872aa36910715b03bab0770b11d35273de1ea3a9f158304"}},{"ruleId":"D2","level":"warning","message":{"text":"BasicPermissionCheck.checkDirectoryPermissionsRecursively (cognitive 28): BasicPermissionCheck.checkDirectoryPermissionsRecursively has cognitive complexity 28 (threshold 15). Drivers by points: if/else 11 (15 pts), error handling 4 (5 pts), boolean chains 3, match/switch 1 (3 pts), loops 1, ternaries 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Diagnostics/Pipes/Checks/BasicPermissionCheck.php"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"8282762a0dd1f8e1347b68e927a60a7dcadc662407f51da833e3ee93d7245a69"}},{"ruleId":"D2","level":"warning","message":{"text":"IniSettingsCheck.handle (cognitive 27): IniSettingsCheck.handle has cognitive complexity 27 (threshold 15). Drivers by points: if/else 18 (19 pts), boolean chains 5, ternaries 1 (2 pts), error handling 1 (nesting depth added 2). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Diagnostics/Pipes/Checks/IniSettingsCheck.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"cab79a7abec3b993cc915f2cc1b48a9dfd707a764cf37658c98b9cdddd24b15b"}},{"ruleId":"D2","level":"warning","message":{"text":"config.validateConfig (cognitive 27): config.validateConfig has cognitive complexity 27 (threshold 15). Drivers by points: boolean chains 11, if/else 10, ternaries 5 (6 pts) (nesting depth added 1). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/config.ts"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bf24e5a938b11aea019ea7253bcf42f65b5ae511a14c48e75fa17ced1e793e0"}},{"ruleId":"D2","level":"warning","message":{"text":"quickNaming.decideKey (cognitive 27): quickNaming.decideKey has cognitive complexity 27 (threshold 15). Drivers by points: ternaries 7 (15 pts), if/else 4 (7 pts), boolean chains 4, match/switch 1 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/quickNaming.ts"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0cd8df28c7888031c2dd95534687f7c89dadcb6f0d3e464d31eba7011124631"}},{"ruleId":"D2","level":"warning","message":{"text":"FileDeleterJob.handle (cognitive 25): FileDeleterJob.handle has cognitive complexity 25 (threshold 15). Drivers by points: if/else 7 (14 pts), error handling 2 (6 pts), loops 2 (4 pts), boolean chains 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/FileDeleterJob.php"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad03365b8e8100f4b7fda6fdf16dbb15f7c47787ea1fe6d2b4da292a53cd7cc9"}},{"ruleId":"D2","level":"warning","message":{"text":"PhotosAddedNotification.handle (cognitive 24): PhotosAddedNotification.handle has cognitive complexity 24 (threshold 15). Drivers by points: if/else 9 (18 pts), loops 2 (3 pts), error handling 1 (2 pts), boolean chains 1 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/PhotosAddedNotification.php"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6b8004e0c04a2f988bf2c7366a6aec0f9eb97e2b6c860069fb0dea686e46b0d"}},{"ruleId":"D2","level":"warning","message":{"text":"HydrateMetadata.handle (cognitive 23): HydrateMetadata.handle has cognitive complexity 23 (threshold 15). Drivers by points: if/else 21, ternaries 1 (2 pts) (nesting depth added 1). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/Pipes/Shared/HydrateMetadata.php"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"b00c9ca816c5fa6f2afedea6f0d524ef7adaf15836e4541b056cf91fb778d469"}},{"ruleId":"D2","level":"warning","message":{"text":"Takedate.handle (cognitive 23): Takedate.handle has cognitive complexity 23 (threshold 15). Drivers by points: if/else 11 (17 pts), boolean chains 2, error handling 2, loops 1, ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/ImageProcessing/Takedate.php"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"b65b29cdb7dc83392bef3e332556dbec5cdc5100e2638072d72b97c3f61ec329"}},{"ruleId":"D2","level":"warning","message":{"text":"VideoData.handle (cognitive 22): VideoData.handle has cognitive complexity 22 (threshold 15). Drivers by points: if/else 9 (17 pts), boolean chains 2, error handling 2, loops 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/ImageProcessing/VideoData.php"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e720bcd28dff42441745372f102779c4c21fcd5fd92e5afcd54254acbda1b0e"}},{"ruleId":"D2","level":"warning","message":{"text":"FaceDetectionController.processFaceResults (cognitive 22): FaceDetectionController.processFaceResults has cognitive complexity 22 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 5 (7 pts), error handling 1 (3 pts), boolean chains 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/AiVision/FaceDetectionController.php"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"48ac5c35e805813a4dfa6aa9570de09bf537058289c13c073e7e83b0fa6c4f8b"}},{"ruleId":"D2","level":"warning","message":{"text":"leftMenu.useLeftMenu.items (cognitive 22): leftMenu.useLeftMenu.items has cognitive complexity 22 (threshold 15). Drivers by points: boolean chains 19, if/else 2, ternaries 1. Of this number, 21 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"57ad4be6f3032ad12854508baab90130025f81c75b9ada203891bd8465029608"}},{"ruleId":"D2","level":"warning","message":{"text":"analyticPhotoLayout.computeTimelinePhotoLayout (cognitive 22): analyticPhotoLayout.computeTimelinePhotoLayout has cognitive complexity 22 (threshold 15). Drivers by points: if/else 5 (10 pts), loops 3 (8 pts), ternaries 2 (3 pts), boolean chains 1 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/photo/analyticPhotoLayout.ts"},"region":{"startLine":301}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1a203018027acb065e1523f4168676c25cb082fa6a9e41b494b45a776659a7c"}},{"ruleId":"D2","level":"warning","message":{"text":"useSearchTokenAssembler.parseTokens (cognitive 21): useSearchTokenAssembler.parseTokens has cognitive complexity 21 (threshold 15). Drivers by points: if/else 19 (20 pts), loops 1 (nesting depth added 1). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useSearchTokenAssembler.ts"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"61485bc8f5813ce30032b1d437bab9cebef0ee409982b9edbd8b560bdcf2fc2e"}},{"ruleId":"D2","level":"warning","message":{"text":"PlaceVideo.handle (cognitive 20): PlaceVideo.handle has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (15 pts), error handling 2 (5 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/Pipes/VideoPartner/PlaceVideo.php"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7234527f10763176dfbbecf533fadf0ec3ce06bd9ef0cb4ecbea27a708e7ff3"}},{"ruleId":"D2","level":"warning","message":{"text":"AlbumConfig.__construct (cognitive 20): AlbumConfig.__construct has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 14, if/else 4, ternaries 2. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/GalleryConfigs/AlbumConfig.php"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f94d2cb5b4e702ff5b17a78cea73663bd832b5bf76da4a20474591df8916c06"}},{"ruleId":"D2","level":"warning","message":{"text":"dragAndSelect.useDragAndSelect.getAlbumBoxesV3 (cognitive 20): dragAndSelect.useDragAndSelect.getAlbumBoxesV3 has cognitive complexity 20 (threshold 15). Drivers by points: ternaries 8 (11 pts), boolean chains 7, if/else 2 (nesting depth added 3). None of this is in the body itself: all 20 points belong to 3 function literals inside it that branch (lines 346, 404, 419). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/dragAndSelect.ts"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"6916368c76233cb5f38f59cd957e08234e63cb6e3f6e843997dde02a37c40ee3"}},{"ruleId":"D2","level":"warning","message":{"text":"BaseArchive.gatherFilenames (cognitive 19): BaseArchive.gatherFilenames has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (9 pts), error handling 1 (3 pts), loops 2 (3 pts), boolean chains 2, ternaries 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/BaseArchive.php"},"region":{"startLine":448}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a3aad7def1dc81da05c2a5a9e7506cb9402f790bd6ebc0aa135c5dc87622c45"}},{"ruleId":"D2","level":"warning","message":{"text":"FixPermissions.fixPermissionsRecursively (cognitive 19): FixPermissions.fixPermissionsRecursively has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (12 pts), boolean chains 2, error handling 2, loops 1 (2 pts), match/switch 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/FixPermissions.php"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"62ecba4791f210ddbd0adb1423ac821dc243c8fec345e148f8d801b415c06f68"}},{"ruleId":"D2","level":"warning","message":{"text":"Sync.executeImport (cognitive 19): Sync.executeImport has cognitive complexity 19 (threshold 15). Drivers by points: error handling 2 (6 pts), if/else 6, boolean chains 5, loops 1 (2 pts) (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/Sync.php"},"region":{"startLine":291}}}],"partialFingerprints":{"codehealthFindingId/v1":"314f0a54b650b51ff6ff2ae17197fa8ffc3bafe06f3cf48eecb15b92959548e3"}},{"ruleId":"D2","level":"warning","message":{"text":"AlbumAccessPermissionListController.buildResource (cognitive 19): AlbumAccessPermissionListController.buildResource has cognitive complexity 19 (threshold 15). Drivers by points: ternaries 9 (18 pts), loops 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Gallery/AlbumAccessPermissionListController.php"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"09c1ea7c6b0c682755158c6f59a52bc9181ac0a1c3a3a33a2f30a84b0b891342"}},{"ruleId":"D2","level":"warning","message":{"text":"dragAndSelect.useDragAndSelect.getPhotoBoxesV3 (cognitive 19): dragAndSelect.useDragAndSelect.getPhotoBoxesV3 has cognitive complexity 19 (threshold 15). Drivers by points: ternaries 7 (17 pts), boolean chains 1, if/else 1 (nesting depth added 10). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/dragAndSelect.ts"},"region":{"startLine":454}}}],"partialFingerprints":{"codehealthFindingId/v1":"b49eda47e4d5cb3799499c573241da979c0470d9ab2d5a058d9e91a20ffc45ea"}},{"ruleId":"D2","level":"warning","message":{"text":"BatchFaceRequest.withValidator (cognitive 18): BatchFaceRequest.withValidator has cognitive complexity 18 (threshold 15). Drivers by points: boolean chains 11, if/else 6 (7 pts) (nesting depth added 1). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Face/BatchFaceRequest.php"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"fcfc2f11b8be734973061c2c9e018be3bb9ba8597f76b49d4460dafa25a189fd"}},{"ruleId":"D2","level":"warning","message":{"text":"check_translations.checkFile (cognitive 18): check_translations.checkFile has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (16 pts), boolean chains 1, loops 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/check_translations.php"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"e18148f46d21218ffbbeec3413897c85ed92e69918283ce1bb5de13c3b032b69"}},{"ruleId":"D2","level":"warning","message":{"text":"albumStatistics.useAlbumsStatistics.getStatistics (cognitive 18): albumStatistics.useAlbumsStatistics.getStatistics has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (16 pts), boolean chains 1, loops 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/albumStatistics.ts"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"dff898dbe61804f02b47d2ce870c460b43afb192ce33f60862eae6d638b9c956"}},{"ruleId":"D2","level":"warning","message":{"text":"useSearchTokenAssembler.assembleTokens (cognitive 18): useSearchTokenAssembler.assembleTokens has cognitive complexity 18 (threshold 15). Drivers by points: if/else 16, boolean chains 1, loops 1. To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useSearchTokenAssembler.ts"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"48c81bc5e04ab25281c8e4ee7395c3fd745e9a148e4227da98f86b11d1bcdc13"}},{"ruleId":"D2","level":"warning","message":{"text":"PlacePhoto.putSourceIntoFinalDestination (cognitive 17): PlacePhoto.putSourceIntoFinalDestination has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (11 pts), error handling 2 (4 pts), boolean chains 2 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/Pipes/Standalone/PlacePhoto.php"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"40ce7f5e5d73d305710701e77e7786c65a431b59303ea998b89a931dfe2d1eac"}},{"ruleId":"D2","level":"warning","message":{"text":"BulkAlbumPatchData.fromValidated (cognitive 17): BulkAlbumPatchData.fromValidated has cognitive complexity 17 (threshold 15). Drivers by points: ternaries 16, boolean chains 1. To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/DTO/BulkAlbumPatchData.php"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"d75442ff1cd705e4d0a0130f590ff1b419736c437f004984368578b70a4eae77"}},{"ruleId":"D2","level":"warning","message":{"text":"InitConfig.__construct (cognitive 17): InitConfig.__construct has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 15, if/else 1, ternaries 1. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/GalleryConfigs/InitConfig.php"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6e6a60ce1598e51ce67d8cfbb29a1f695aac5b0f90982dcf503193f605da010"}},{"ruleId":"D2","level":"warning","message":{"text":"contextMenu.useContextMenu.photoMenu (cognitive 17): contextMenu.useContextMenu.photoMenu has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (8 pts), boolean chains 7, ternaries 1 (2 pts) (nesting depth added 2). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4f6ab7257e59814327e76d09dc30550ef3be20bf21829decdafe5170f97ebc3"}},{"ruleId":"D2","level":"warning","message":{"text":"contextMenu.useContextMenu.photoMenu (cognitive 17): contextMenu.useContextMenu.photoMenu has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (8 pts), boolean chains 7, ternaries 1 (2 pts) (nesting depth added 2). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/contextMenu.ts"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b6dccfcfaf11dcaccfce751245f7b72923be88bba93f811d2ec70a55115af1d"}},{"ruleId":"D2","level":"warning","message":{"text":"RequirementsChecker.check (cognitive 16): RequirementsChecker.check has cognitive complexity 16 (threshold 15). Drivers by points: loops 3 (7 pts), if/else 3 (6 pts), boolean chains 3 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/InstallUpdate/RequirementsChecker.php"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f7bba6bb2b0a380bdd3400bedc752f3edd5f93360a4cde395422032a8eeb60f"}},{"ruleId":"D2","level":"warning","message":{"text":"ExtractMotionPhotos.handle (cognitive 16): ExtractMotionPhotos.handle has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (6 pts), boolean chains 4, ternaries 2 (3 pts), error handling 1, loops 1, match/switch 1 (nesting depth added 2). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/ImageProcessing/ExtractMotionPhotos.php"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"078dc7ef6da19c615843f8d9a6708e23330927ebdfdec4bd8c34537425e67014"}},{"ruleId":"D2","level":"warning","message":{"text":"ExtractZip.validate_zip (cognitive 16): ExtractZip.validate_zip has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (11 pts), error handling 1 (2 pts), loops 1 (2 pts), boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/ExtractZip.php"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4be0aa0b3e7955623a97cf81516c6370bf060172b48156e34fdd778fcad5d0c"}},{"ruleId":"D2","level":"warning","message":{"text":"uploadEvents.useMouseEvents.onPaste (cognitive 16): uploadEvents.useMouseEvents.onPaste has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 1 (2 pts), boolean chains 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/uploadEvents.ts"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"56666708243f46d7ed14fa1a6ee17965ad6b236ad7d5e26322cb8838cf565eb3"}},{"ruleId":"D2","level":"warning","message":{"text":"uploadEvents.useMouseEvents.onPaste (cognitive 16): uploadEvents.useMouseEvents.onPaste has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 1 (2 pts), boolean chains 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/uploadEvents.ts"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"d50e6a4cfdcbec4451cd93a2ed61b3690bd1349ccc098ebbed64c5cc2b6633f3"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useSphereViewer.useSphereViewer: FunctionTooLong \u2014 useSphereViewer runs 325 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 225 over it, 3.25\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useSphereViewer.ts"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8b5a26a96a09cf13aea59014ef12c3e42e445b8b5c89e31e46d1d87849e72e3"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: dragAndSelect.useDragAndSelect: FunctionTooLong \u2014 useDragAndSelect runs 306 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 206 over it, 3.06\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/dragAndSelect.ts"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"6cff4d604632f2df5cc21d455a672db796a6fa7cbc02c2a87a13b8fc12076cc3"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: contextMenu.useContextMenu: FunctionTooLong \u2014 useContextMenu runs 261 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 161 over it, 2.61\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"2710c865dfb564a1a49e3eee7e2c8aed372f4c329ef868d0ddb9f7a5307d694f"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: contextMenu.useContextMenu: FunctionTooLong \u2014 useContextMenu runs 261 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 161 over it, 2.61\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/contextMenu.ts"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"6793a0607d4e638df355a8cb1f687ab6cd65002400d51d24d1d226798a1aa27d"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: usePanZoom.usePanZoom: FunctionTooLong \u2014 usePanZoom runs 252 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 152 over it, 2.52\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/usePanZoom.ts"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"80e81c81d5ff090d0d3ef7e7d066858f5dc5f40b12c11bf4d1eb3bf03e58ae1d"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useQuickNamingSession.useQuickNamingSession: FunctionTooLong \u2014 useQuickNamingSession runs 240 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 140 over it, 2.40\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useQuickNamingSession.ts"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"273bf1416fb8f38a64a8457c695adda250dbc27c9aabdbcfc189bf5eb838c871"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: leftMenu.useLeftMenu: FunctionTooLong \u2014 useLeftMenu runs 218 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 118 over it, 2.18\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"78aad2797615e81c04d58cf6a418ed7a9456c887692146fd3bc3b505018d7727"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: CacheKeyProvider: TooManyMethods \u2014 58 methods. The bar is 30 methods; this is 28 over it, 1.93\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Cache/CacheKeyProvider.php"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfd1be72476fd25e9f9dfad09c860441dc7ec61d1d796a6c123bd2bca5a5e60b"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: leftMenu.useLeftMenu: FunctionTooLong \u2014 useLeftMenu runs 186 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 86 over it, 1.86\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/leftMenu.ts"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"a080be1480131369bd244bc8da49b6a38955cd78808ba6d7fcf6af7e4d65b903"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useAdminTiles.useAdminTiles: FunctionTooLong \u2014 useAdminTiles runs 178 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 78 over it, 1.78\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useAdminTiles.ts"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d737b2d12042f7d414f018a8d91d8495394793b732b8ac2a066552217c1f4bf"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: selections.useSelection: FunctionTooLong \u2014 useSelection runs 174 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 74 over it, 1.74\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/selections/selections.ts"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb50756fe3ce22b977c4d47892a09a3b1dda27bb212481ae87610d688c571a79"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: treeOperations.useTreeOperations: FunctionTooLong \u2014 useTreeOperations runs 167 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 67 over it, 1.67\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/treeOperations.ts"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"a112dbc68eac93dcb0db78d4ee5b3466abad578c33a6afd52c7e7a85dab2ab5c"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: leftMenu.useLeftMenu.items: FunctionTooLong \u2014 useLeftMenu.items runs 152 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 52 over it, 1.52\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"d98b76a529459f58e58da97aa14fdb879caf1b592de422dfb418d9154713695e"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: phpDateFormat.phpDateFormat: FunctionTooLong \u2014 phpDateFormat runs 148 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 48 over it, 1.48\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/phpDateFormat.ts"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"e285665231e323cd38803b63ba278484b09705a33adbebbdb23dff4d7bb1b349"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: getPreviewInfo.usePreviewData: FunctionTooLong \u2014 usePreviewData runs 143 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 43 over it, 1.43\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/preview/getPreviewInfo.ts"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d8864e20fb80c314971a75eda6e28df389b10ce13cd0553e3d56a0938cf1c5d"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: buyMeActions.useBuyMeActions: FunctionTooLong \u2014 useBuyMeActions runs 137 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 37 over it, 1.37\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/buyMeActions.ts"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"18766bcb39a1b32482a93de86ecc25b3cc099730aae01b653d225d084d4bfef7"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: AlbumPolicy: TooManyMethods \u2014 40 methods. The bar is 30 methods; this is 10 over it, 1.33\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Policies/AlbumPolicy.php"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"a362f8e4ead929b4eea3458bb0326f5a77af676901ecbae09d5a720cf1fb3a7c"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useSpotlightGalleryActions.useSpotlightGalleryActions: FunctionTooLong \u2014 useSpotlightGalleryActions runs 132 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 32 over it, 1.32\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/spotlight/useSpotlightGalleryActions.ts"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"7100c8345295e1af74fc885bae652a3f617a22b409edd96d5d0a5c196b2e0918"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useAdminTiles.useAdminTiles: FunctionTooLong \u2014 useAdminTiles runs 130 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 30 over it, 1.30\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useAdminTiles.ts"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"29c12919c4efbc4a431e63d9a268bcedd6648e7f2a5cfc8a204f25e1a7145d8a"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: InitConfig.__construct: MethodTooLong \u2014 __construct runs 127 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 27 over it, 1.27\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/GalleryConfigs/InitConfig.php"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"827ebd606208b98ac4f29992acf965a79bab66b282a91bb710be35689cf75c40"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: QueryPhotoDetails.buildResource: MethodTooLong \u2014 buildResource runs 122 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 22 over it, 1.22\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoDetails.php"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"da5d93dc810721e20b29a07896668d5bb4a5bf0251f8e5c41ef142f61e0d24ae"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: Extractor.createFromFile: MethodTooLong \u2014 createFromFile runs 122 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 22 over it, 1.22\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Metadata/Extractor.php"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc78b0b971fdc37ddf8c2288f8d30119da8a1a3bb3e0352eb578cb586c97beb1"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: Album: TooManyMethods \u2014 35 methods. The bar is 30 methods; this is 5 over it, 1.17\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Album.php"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ac475703334a67ab3449a1ce98e750635b82ebcad581e78de55d45c20f8d431"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: galleryModals.useGalleryModals: FunctionTooLong \u2014 useGalleryModals runs 102 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 2 over it, 1.02\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/modalsTriggers/galleryModals.ts"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"d346e750aa0f96c273a88dfb6738cf365bb1bfc77c1eab3b72cf664db6a7996d"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: getPreviewInfo.usePreviewData.getInsightsData: FunctionTooLong \u2014 usePreviewData.getInsightsData runs 102 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 2 over it, 1.02\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/preview/getPreviewInfo.ts"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dbe4d892d7a3322bb3a2cbbf2abf941daa705eec1cbf7bbdf2ec65d94f8af8e"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (24 corresponding lines): app/Services/TitleSplitter.php:56-79 | database/migrations/TemporaryModels/TitleSplitter.php:50-73 \u2014 These two members are one piece of code written twice and then edited apart: 24 consecutive lines correspond almost exactly, broken only by small local edits. Most of that correspondence is NOT reported as duplicated blocks below \u2014 the edits cut it into fragments and only the largest of them clear the block floor, so the rows below understate it. The repair is at the members\u0027 grain \u2014 factor the shared implementation into one the two call with their differences as parameters or as an injected step, or, where the difference is systematic (an extra return value, one transport against another), generate one from the other. Left alone, the next edit has to be made twice and the two will drift further apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/TitleSplitter.php"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"e434459b25f4565e6442c5408c8d725bdb14ad4f4d6a3390f548cf13fa44986c"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (7 members, 50\u002B identical tokens): app/Actions/Face/QueryFaceQueue.php:123-164 | app/Actions/Photo/StructOfArrays/QueryPhotoDetails.php:107-256 | app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:185-264 | app/Actions/Search/StructOfArrays/QuerySearchPhotos.php:197-282 | app/Http/Controllers/Gallery/AlbumAccessPermissionListController.php:98-156 | app/Http/Controllers/Gallery/AlbumListController.php:220-287 | app/Http/Controllers/Gallery/FlowListController.php:101-168 \u2014 These 7 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 7 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 7 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Face/QueryFaceQueue.php"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"22923acac65dc359680dc383ea949f4fbba8d6cbab1f165db51f263329bdd993"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): app/Exceptions/Handlers/AccessDBDenied.php:44-56 | app/Exceptions/Handlers/AdminSetterHandler.php:58-85 | app/Exceptions/Handlers/InstallationHandler.php:58-74 | app/Exceptions/Handlers/MigrationHandler.php:59-71 | app/Exceptions/Handlers/NoEncryptionKey.php:44-56 \u2014 These 5 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 5 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 5 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Exceptions/Handlers/AccessDBDenied.php"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c406fbc910223787661ee563ec15599ac4d51707406f7223d7f7ca2e7e3742f"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): app/SmartAlbums/FiveStarsAlbum.php:50-64 | app/SmartAlbums/FourStarsAlbum.php:51-65 | app/SmartAlbums/ThreeStarsAlbum.php:51-65 | app/SmartAlbums/TwoStarsAlbum.php:53-67 | app/SmartAlbums/UnratedAlbum.php:50-64 \u2014 These 5 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 5 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 5 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/SmartAlbums/FiveStarsAlbum.php"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"24481f0ba5a47723928caa8a1628227c01264c4dc85576baeb28eb4c20c5ff4f"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): app/Actions/Album/BaseArchive.php:267-289 | app/Actions/Album/BaseArchive.php:311-353 | app/Actions/Photo/BaseArchive.php:199-261 | app/Actions/Photo/BaseArchive.php:332-465 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/BaseArchive.php"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2848761bad95e113b30ec1316ed450ea4beb4fefe625afea52e7320a065f4c9"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): app/Actions/Tag/DeleteTag.php:41-69 | app/Actions/Tag/MergeTag.php:71-111 | app/Actions/Tag/MergeTag.php:117-157 | app/Actions/Tag/MergeTag.php:169-211 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Tag/DeleteTag.php"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a54168f776c614d560e0d1ef4cd214bb04e4738baf3b663f0da521b37e9e023"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): app/Rules/BooleanRequireSupportRule.php:32-48 | app/Rules/EnumRequireSupportRule.php:42-68 | app/Rules/IntegerRequireSupportRule.php:33-48 | app/Rules/StringRequireSupportRule.php:34-50 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Rules/BooleanRequireSupportRule.php"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a3726f93f26a8131114e4deb266e3588d6f371a4e0244117ce1cf83097b0505"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): app/Services/Image/FacialRecognitionService.php:117-138 | app/Services/Image/FacialRecognitionService.php:149-177 | app/Services/Image/NsfwDetectionService.php:47-68 | app/Services/Image/NsfwDetectionService.php:77-98 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/FacialRecognitionService.php"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a032e4158b81f3d55053b715241b65339cc486892629d105f044dccf4eb9a18"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (41 lines \u00D7 3): app/Actions/Tag/MergeTag.php:71-111 | app/Actions/Tag/MergeTag.php:117-157 | app/Actions/Tag/MergeTag.php:169-209 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Tag/MergeTag.php"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"cff4e3b284c5e176058df9abf68713d78d85a9f1eeee1ffe43aaf6d71ee7bfbb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2): app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php:128-160 | app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php:210-242 \u2014 before extracting anything, compare \u0060app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php\u0060 and \u0060app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php:128\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"f698f86c84031d256960d860d5be0cd0df3ded1a4ae1930e027e4f2de0f81fc0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2): app/Console/Commands/RecomputeAlbumSizes.php:101-133 | app/Console/Commands/RecomputeAlbumStats.php:101-133 \u2014 before extracting anything, compare \u0060app/Console/Commands/RecomputeAlbumSizes.php\u0060 and \u0060app/Console/Commands/RecomputeAlbumStats.php\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumSizes.php"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"201cabea35a192371b26130b76176ecd4e9559cd12732698954907a0a7946ce4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (32 lines \u00D7 2): app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php:49-80 | app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php:137-168 \u2014 before extracting anything, compare \u0060app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php\u0060 and \u0060app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd13d52e085b3fd3b70e27d6b15a9561afee26dce30f8398080930143c59eaa3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (32 lines \u00D7 2): app/Repositories/ConfigManager.php:207-238 | app/Repositories/ConfigManager.php:251-282 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Repositories/ConfigManager.php"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"f91f454da943ffe3cf7621cbd3c896037f96f4551d3e09b1978aca1d451a31d4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 2): app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:214-242 | app/Actions/Search/StructOfArrays/QuerySearchPhotos.php:231-259 \u2014 before extracting anything, compare \u0060app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php\u0060 and \u0060app/Actions/Search/StructOfArrays/QuerySearchPhotos.php\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 102 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:214\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:213\u0060 calls \u0060normalizeId\u0060 and \u0060app/Actions/Search/StructOfArrays/QuerySearchPhotos.php:230\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c9f08831a890fce5ce014c75bf34d944469669edab9357d923476aad82b97b9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201329 lines \u00D7 2): app/Policies/AlbumQueryPolicy.php:367-395 | app/Policies/AlbumQueryPolicy.php:459-478 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Policies/AlbumQueryPolicy.php:367\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Policies/AlbumQueryPolicy.php"},"region":{"startLine":367}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c13fe84c4f5e853b240d7a6d47beda93c018d6a9dc31aea51d565be411f1d21"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24\u201327 lines \u00D7 2): app/Policies/PhotoPolicy.php:293-319 | app/Policies/PhotoPolicy.php:364-387 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Policies/PhotoPolicy.php"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"b54f4eba728e8f3d697907caacbaeded0c8bc90832f1c9f5d984f9219aec9bef"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24\u201326 lines \u00D7 2): app/Actions/Photo/BaseArchive.php:226-249 | app/Actions/Photo/BaseArchive.php:427-452 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Photo/BaseArchive.php:226\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/BaseArchive.php"},"region":{"startLine":226}}}],"partialFingerprints":{"codehealthFindingId/v1":"5aa1c904103c3b51264a534bbed52101d1ec51a32b95e0baa81397bab4a068eb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2): app/Rules/ExtensionRule.php:45-70 | app/Rules/FileUuidRule.php:47-72 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Rules/ExtensionRule.php"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e38b8c1858580657afa055f4f77e41b40f8afc6efa2f9808d627c3561a4fa78"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23\u201325 lines \u00D7 2): app/Actions/Album/BaseArchive.php:214-238 | app/Actions/Album/BaseArchive.php:470-492 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/BaseArchive.php"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"64779c807dbe056ecc88d1ae71399c529ac39136046f6cc380f97a09bf069b74"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): app/Console/Commands/RecomputeAlbumSizes.php:140-164 | app/Console/Commands/RecomputeAlbumStats.php:141-165 \u2014 before extracting anything, compare \u0060app/Console/Commands/RecomputeAlbumSizes.php\u0060 and \u0060app/Console/Commands/RecomputeAlbumStats.php\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Console/Commands/RecomputeAlbumSizes.php:140\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumSizes.php"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"de55ecea72108466eb3bf31cd086528111728607461ebbb98c23fddfb701ad2f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 3): app/Http/Requests/ShopManagement/PurchasableAlbumRequest.php:103-125 | app/Http/Requests/ShopManagement/PurchasablePhotoRequest.php:113-135 | app/Http/Requests/ShopManagement/UpdatePurchasablePriceRequest.php:90-112 \u2014 before extracting anything, compare \u0060app/Http/Requests/ShopManagement/PurchasableAlbumRequest.php\u0060 and \u0060app/Http/Requests/ShopManagement/UpdatePurchasablePriceRequest.php\u0060 as WHOLE FILES: 89% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/ShopManagement/PurchasableAlbumRequest.php:103\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060app/Http/Requests/ShopManagement/PurchasableAlbumRequest.php:127\u0060 calls \u0060toBoolean\u0060 and \u0060app/Http/Requests/ShopManagement/PurchasablePhotoRequest.php:136\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/ShopManagement/PurchasableAlbumRequest.php"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"09b507fd2d3d173b9d223832f515d5411ef447d5be1e2d2f485175b9a96e3610"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 3): app/Actions/Album/StructOfArrays/Traits/GrantsAlbumRights.php:79-100 | app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php:404-425 | app/Http/Controllers/Gallery/AlbumListing/AlbumTagController.php:108-129 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Album/StructOfArrays/Traits/GrantsAlbumRights.php:79\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/StructOfArrays/Traits/GrantsAlbumRights.php"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa03792292c96375f309412f3118f7948aefe2786a0bca1c3aa155ef8acc6adf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): app/Actions/Diagnostics/Pipes/Checks/AiVisionFaceRecognitionServiceCheck.php:46-67 | app/Actions/Diagnostics/Pipes/Checks/AiVisionNsfwServiceCheck.php:53-74 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Diagnostics/Pipes/Checks/AiVisionFaceRecognitionServiceCheck.php:46\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Diagnostics/Pipes/Checks/AiVisionFaceRecognitionServiceCheck.php"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e076f0c5e2a7651b694d99a20b895745684deb4e1b7bf6a3bb1be54ee8cb659"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): app/Http/Controllers/Gallery/AlbumController.php:194-214 | app/Http/Controllers/Gallery/AlbumController.php:231-251 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Gallery/AlbumController.php"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b7de67a9c51962714328f7fa7528870842e28ff3a46f3e1fcabfc0871c38654"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): app/Http/Controllers/Gallery/AlbumTagsController.php:104-124 | app/Http/Controllers/Gallery/AlbumTagsController.php:137-157 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Gallery/AlbumTagsController.php"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e4f0fe71d7d8ab17bee4b0b65570a265c21441af7aa15dddbbcbf18e0da5e82"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u201320 lines \u00D7 3): app/Http/Requests/Album/UpdateAlbumRequest.php:235-238 | app/Http/Requests/Album/UpdatePersonAlbumRequest.php:103-122 | app/Http/Requests/Album/UpdateTagAlbumRequest.php:103-122 \u2014 before extracting anything, compare \u0060app/Http/Requests/Album/UpdatePersonAlbumRequest.php\u0060 and \u0060app/Http/Requests/Album/UpdateTagAlbumRequest.php\u0060 as WHOLE FILES: 82% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/Album/UpdatePersonAlbumRequest.php:103\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060app/Http/Requests/Album/UpdatePersonAlbumRequest.php:122\u0060 calls \u0060array_key_exists\u0060 and \u0060app/Http/Requests/Album/UpdateAlbumRequest.php:238\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Album/UpdateAlbumRequest.php"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"04151a7c17992756b0798bf5327202be784408422502d21b2d6cccae863fd4bd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201319 lines \u00D7 2): app/SmartAlbums/BestPicturesAlbum.php:62-76 | app/SmartAlbums/MyBestPicturesAlbum.php:61-79 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/SmartAlbums/BestPicturesAlbum.php"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"ecbfd6be020f8ab85f2f138c1a788e9a29fe4bf5f564aaf13a0f7e8a98c48603"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): app/Actions/Import/Pipes/DeleteMissingAlbums.php:75-92 | app/Actions/Import/Pipes/DeleteMissingPhotos.php:82-99 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Import/Pipes/DeleteMissingAlbums.php"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd0c4224409a814389be9bafa1fae074a25b9fc9367498bc4ad0e43a97378d45"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php:110-126 | app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php:188-204 \u2014 before extracting anything, compare \u0060app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php\u0060 and \u0060app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php:110\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dd3cc8a7a5ddb9988639344319fff274263136f8b0fe9d7fa76f70a850f7b8d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201317 lines \u00D7 2): app/Http/Controllers/Admin/Maintenance/DestroyDismissedFaces.php:47-62 | app/Http/Controllers/AiVision/FaceController.php:184-200 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Admin/Maintenance/DestroyDismissedFaces.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e0c492144b44ca9ae3cb4d3ee8b9ead6cbb8cb7aa9ac70e1c9461948879ec0d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): app/Http/Requests/Album/GetAlbumChildrenRequest.php:68-84 | app/Http/Requests/Album/GetAlbumPhotosRequest.php:111-127 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Album/GetAlbumChildrenRequest.php"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4976c28ca98cdb041bad078c15e1aa138104cc2a366cd5298ad37f5f8dd12ed"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): app/Models/Extensions/ForwardsToParentImplementation.php:132-148 | app/Models/Extensions/ThrowsConsistentExceptions.php:87-103 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Extensions/ForwardsToParentImplementation.php"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"6278204a1dcebcb7f689fd11fa90682f0b7ac9b8a20f2ddbff847776a58e1d58"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): app/Services/TitleSplitter.php:56-72 | database/migrations/TemporaryModels/TitleSplitter.php:50-66 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/TitleSplitter.php"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e7e46de369a933143c74bc2e668ec791cc64b76c3bf0f6c35d5444123d5ea7f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:195-210 | app/Actions/Search/StructOfArrays/QuerySearchPhotos.php:207-222 \u2014 before extracting anything, compare \u0060app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php\u0060 and \u0060app/Actions/Search/StructOfArrays/QuerySearchPhotos.php\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 102 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:195\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f9f9528ebc5ebf016f84dee0c6c326a074d62e5a516b790ee6116133941c739"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): app/Console/Commands/RecomputeAlbumSizes.php:56-71 | app/Console/Commands/RecomputeAlbumStats.php:56-71 \u2014 before extracting anything, compare \u0060app/Console/Commands/RecomputeAlbumSizes.php\u0060 and \u0060app/Console/Commands/RecomputeAlbumStats.php\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Console/Commands/RecomputeAlbumSizes.php:56\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumSizes.php"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"45491b68884b092a74a5b9ed70c4dcac7b4c1d1a01bd4e094fcdd07faf796c0a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): app/Image/Files/NativeLocalFile.php:86-101 | app/Image/Files/NativeLocalFile.php:121-136 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Image/Files/NativeLocalFile.php:86\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Image/Files/NativeLocalFile.php"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa89c9c1bce97f3cec78f2ac282e87f623ccd29ad158aa52e3dcdd84d3cafef9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): app/Models/Builders/PersonAlbumBuilder.php:34-49 | app/Models/Builders/TagAlbumBuilder.php:45-60 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Builders/PersonAlbumBuilder.php"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"afa0e758a4ff4593baff58a6d0e55f95a9b1ea9c0b416fd2ae9d1dcf4be523e7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): app/Services/Image/FacialRecognitionService.php:123-138 | app/Services/Image/NsfwDetectionService.php:53-68 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Services/Image/FacialRecognitionService.php:123\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/FacialRecognitionService.php"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a4d95dc4cbe06b8133a68e0e0413403a48f3803428caa9a9b901019063305f2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201315 lines \u00D7 4): app/Actions/Album/BaseArchive.php:275-289 | app/Actions/Album/BaseArchive.php:342-353 | app/Actions/Photo/BaseArchive.php:251-261 | app/Actions/Photo/BaseArchive.php:453-465 \u2014 there are 4 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 4 sites; resolving a subset leaves the remainder to drift apart. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Album/BaseArchive.php:275\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/BaseArchive.php"},"region":{"startLine":275}}}],"partialFingerprints":{"codehealthFindingId/v1":"47158fb6d4e21c951387f214fd7e852838d6e852c3c2ade859549b6c6d47eb91"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 4): app/Rules/BooleanRequireSupportRule.php:34-48 | app/Rules/EnumRequireSupportRule.php:54-68 | app/Rules/IntegerRequireSupportRule.php:34-48 | app/Rules/StringRequireSupportRule.php:36-50 \u2014 before extracting anything, compare \u0060app/Rules/BooleanRequireSupportRule.php\u0060 and \u0060app/Rules/EnumRequireSupportRule.php\u0060 as WHOLE FILES: 85% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Rules/BooleanRequireSupportRule.php:34\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Rules/BooleanRequireSupportRule.php"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee02fbb386bb48be87ead100d4e7b8bef98191da693350e5922b12737cbd8cd7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:101-114 | app/Actions/Search/StructOfArrays/QuerySearchPhotos.php:99-112 \u2014 before extracting anything, compare \u0060app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php\u0060 and \u0060app/Actions/Search/StructOfArrays/QuerySearchPhotos.php\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 102 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:101\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"dac3b94d852948bba9615e4236e33271a51463ce5a503b7a656a0c6887275291"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201314 lines \u00D7 2): app/Actions/Photo/Timeline.php:47-59 | app/Actions/Photo/Timeline.php:121-134 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Photo/Timeline.php:47\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/Timeline.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3f079aac32de02fa35cb35b0c3fbea50f6d386851e9b699daef740b1a47a885"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): app/Console/Commands/ImageProcessing/Detect360.php:63-76 | app/Console/Commands/ImageProcessing/ExtractMotionPhotos.php:101-114 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Console/Commands/ImageProcessing/Detect360.php:63\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/ImageProcessing/Detect360.php"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5ebb1753cc9f32cc404c9adc5a1c1720d154f4592d47729e11b3e24b02d9f75"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): app/Http/Controllers/Gallery/AlbumListing/AlbumChildrenController.php:136-149 | app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php:104-117 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Gallery/AlbumListing/AlbumChildrenController.php"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"61ca9410ac040b9b4c04e36a38a6a59bacb7a73211fe1518411a6d8f2ca1a91c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): app/Http/Controllers/Gallery/AlbumListing/AlbumChildrenController.php:181-194 | app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php:356-369 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Gallery/AlbumListing/AlbumChildrenController.php"},"region":{"startLine":181}}}],"partialFingerprints":{"codehealthFindingId/v1":"388713dc0f3c7c6fa659a5c3bce3a5e879a931cdcad0018cbc92d82ff4ac0868"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201314 lines \u00D7 2): app/Models/PersonAlbum.php:133-143 | app/Models/TagAlbum.php:187-200 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060app/Models/TagAlbum.php:184\u0060 calls \u0060createFromPhoto\u0060 and \u0060app/Models/PersonAlbum.php:132\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PersonAlbum.php"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"66b5da47cc0f9cec7d0f28917314e811fbb8681e961280bafd0fe6aa5b11f999"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): app/Services/Image/FacialRecognitionService.php:155-168 | app/Services/Image/NsfwDetectionService.php:83-96 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Services/Image/FacialRecognitionService.php:155\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/FacialRecognitionService.php"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fa36e7ad344a19ee96fba72bb119a9d1376df616819e442a5136cbe26deb610"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 4): app/Services/Image/FacialRecognitionService.php:117-129 | app/Services/Image/FacialRecognitionService.php:149-161 | app/Services/Image/NsfwDetectionService.php:47-59 | app/Services/Image/NsfwDetectionService.php:77-89 \u2014 there are 4 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 4 sites; resolving a subset leaves the remainder to drift apart. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Services/Image/FacialRecognitionService.php:117\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/FacialRecognitionService.php"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"c86fcde35326774056ff7cd2c5f67e8b47f711d4501f5e09b1871f6b33e13675"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 4): app/SmartAlbums/FiveStarsAlbum.php:50-62 | app/SmartAlbums/FourStarsAlbum.php:51-63 | app/SmartAlbums/ThreeStarsAlbum.php:51-63 | app/SmartAlbums/TwoStarsAlbum.php:53-65 \u2014 before extracting anything, compare \u0060app/SmartAlbums/FiveStarsAlbum.php\u0060 and \u0060app/SmartAlbums/FourStarsAlbum.php\u0060 as WHOLE FILES: 84% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/SmartAlbums/FiveStarsAlbum.php"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"9885c5c72bf3c868d08dc9dd8224cc304ff1ad231e6ba135911c86778a112a1d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 2): app/Actions/Album/BaseArchive.php:164-175 | app/Actions/Album/BaseArchive.php:450-462 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/BaseArchive.php"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"62ba512bfb4da9408b38777d88c8831999611d7614e647e25912424bfed49937"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): app/Actions/Statistics/Spaces.php:260-272 | app/Actions/Statistics/Spaces.php:376-388 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Statistics/Spaces.php"},"region":{"startLine":260}}}],"partialFingerprints":{"codehealthFindingId/v1":"496d9ecb4f57fdb8380471ff929cd5e789ac39c8eb859ceb716b579c4ea8deb8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): app/Http/Controllers/Admin/Maintenance/PurgeOrphanFaceEmbeddings.php:38-50 | app/Http/Controllers/Admin/Maintenance/SyncFaceEmbeddings.php:34-46 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Admin/Maintenance/PurgeOrphanFaceEmbeddings.php"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"a40ef898279bd0c79e189a04e07f691c321a58bdde232c2a1f755396dc6bcd60"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 2): app/Http/Controllers/Install/SetUpAdminController.php:47-58 | app/Http/Controllers/ProfileController.php:62-74 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Install/SetUpAdminController.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"55484c4182ade0b188876eb67bc54a6624a30a63791bc23afcfb5e3149614d38"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): app/Relations/HasManyPhotosByTag.php:152-164 | app/Services/PersonAlbumMatcher.php:116-128 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Relations/HasManyPhotosByTag.php:152\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060app/Services/PersonAlbumMatcher.php:129\u0060 calls \u0060where\u0060 and \u0060app/Relations/HasManyPhotosByTag.php:165\u0060 does not \u2014 after which the two agree again for 4 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Relations/HasManyPhotosByTag.php"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa51abf3fb9e93d43998ef814abfb0741d726c6201afcc7b7ef30c844924b0e6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:194-205 | app/Actions/Search/StructOfArrays/QuerySearchPhotos.php:206-217 | app/Http/Controllers/Gallery/AlbumAccessPermissionListController.php:105-116 \u2014 before extracting anything, compare \u0060app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php\u0060 and \u0060app/Actions/Search/StructOfArrays/QuerySearchPhotos.php\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 102 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:194\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"f901d0d615b76dc2f4aa1056f73861556c51d4863905109f5ed4280fad0e6518"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): app/Actions/Statistics/Counts.php:33-44 | app/Actions/Statistics/Counts.php:58-69 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Statistics/Counts.php"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5eb3d24f370b28a6024c4a5ccebe0a3ad5318c62404124eeff0f44b3d52c8bf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): app/DTO/WebhookPayload.php:40-51 | app/DTO/WebhookPayload.php:70-81 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/DTO/WebhookPayload.php:40\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/DTO/WebhookPayload.php"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b0db83f8548a49a60e310a03e12c1143506a440bed0df3e9f1ea46cad946825"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): app/Jobs/RecomputeAlbumSizeJob.php:114-125 | app/Jobs/RecomputeAlbumStatsJob.php:141-152 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Jobs/RecomputeAlbumSizeJob.php:114\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputeAlbumSizeJob.php"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"3538b477b70e0c5e32134ca75c774260655ce1e74eae5b1726e430462601bda4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): database/factories/OrderItemFactory.php:94-105 | database/factories/OrderItemFactory.php:117-128 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/factories/OrderItemFactory.php"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"e34139c83cee137556b67c56b249ab3b73107b764af53cfb623071c8e85d257a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 7): app/Actions/Face/QueryFaceQueue.php:127-137 | app/Actions/Photo/StructOfArrays/QueryPhotoDetails.php:144-155 | app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:194-205 | app/Actions/Search/StructOfArrays/QuerySearchPhotos.php:206-217 | app/Http/Controllers/Gallery/AlbumAccessPermissionListController.php:105-116 | app/Http/Controllers/Gallery/AlbumListController.php:230-241 | app/Http/Controllers/Gallery/FlowListController.php:113-124 \u2014 before extracting anything, compare \u0060app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php\u0060 and \u0060app/Actions/Search/StructOfArrays/QuerySearchPhotos.php\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 102 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Face/QueryFaceQueue.php:127\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Face/QueryFaceQueue.php"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"da0a8261eb2a60fa2ba8ff08e60887b3cf9a68ce33cd9713947fe764f43d62ee"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php:114-124 | app/Http/Controllers/Gallery/AlbumListController.php:149-159 | app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php:192-202 \u2014 before extracting anything, compare \u0060app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php\u0060 and \u0060app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php:114\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/StructOfArrays/BuildAlbumDataResource.php"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"c83fc68c209310339562cadb95dd9c5fd774ebd9fe0e48096a1185458f946e1f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): app/Exceptions/Handlers/AccessDBDenied.php:46-56 | app/Exceptions/Handlers/MigrationHandler.php:61-71 | app/Exceptions/Handlers/NoEncryptionKey.php:46-56 \u2014 before extracting anything, compare \u0060app/Exceptions/Handlers/AccessDBDenied.php\u0060 and \u0060app/Exceptions/Handlers/NoEncryptionKey.php\u0060 as WHOLE FILES: 83% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Exceptions/Handlers/AccessDBDenied.php:46\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Exceptions/Handlers/AccessDBDenied.php"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"f032bd8526f2de0774c6655c8e7072f8350e6823f1b37793d084cf4f3b0ce610"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201311 lines \u00D7 2): app/Actions/Statistics/Spaces.php:387-397 | app/Actions/Statistics/Spaces.php:444-452 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Statistics/Spaces.php:387\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Statistics/Spaces.php"},"region":{"startLine":387}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ab5e947d6d9f159e370189f1238bbf3a514cf1f38995e2e75db309c4d29cb34"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): app/Actions/Tag/DeleteTag.php:43-53 | app/Actions/Tag/DeleteTag.php:55-65 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Tag/DeleteTag.php"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"45932dd2303594550565f68307089954cf9417a63c2222c88322e3237246f8ad"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): app/Console/Commands/RecomputeAlbumSizes.php:74-84 | app/Console/Commands/RecomputeAlbumStats.php:74-84 \u2014 before extracting anything, compare \u0060app/Console/Commands/RecomputeAlbumSizes.php\u0060 and \u0060app/Console/Commands/RecomputeAlbumStats.php\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Console/Commands/RecomputeAlbumSizes.php:74\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumSizes.php"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fbdacd2d97165d4e113cbb9e784b08bb6ce174cb81f2bf03a6e2552ab5fdb90"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): app/DTO/BulkAlbumPatchData.php:108-118 | app/Http/Resources/Admin/BulkAlbumResource.php:89-99 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/DTO/BulkAlbumPatchData.php"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"2144acc5abab987a5b8350f567ac93cbae3200ea1afd1ecc9d6d88d22ebf4925"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): app/DTO/Delete/PhotosToBeDeletedDTO.php:208-218 | app/DTO/Delete/PhotosToBeDeletedDTO.php:242-252 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/DTO/Delete/PhotosToBeDeletedDTO.php:208\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/DTO/Delete/PhotosToBeDeletedDTO.php"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a02e206a6660aa875805b1ea4865e892844194d46535a716fd56b06911cb47e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): app/Http/Controllers/Admin/UserManagementController.php:58-68 | app/Http/Controllers/Admin/UserManagementController.php:93-103 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Controllers/Admin/UserManagementController.php:58\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Admin/UserManagementController.php"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6801ff7e9dac0da151c507d8b66d52c554919cb69be884e833cccfc98928cfc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): app/Http/Controllers/Gallery/MapListingController.php:62-72 | app/Http/Controllers/Gallery/MapListingController.php:91-101 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Controllers/Gallery/MapListingController.php:62\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Gallery/MapListingController.php"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"10e2ea86c536e3939d687def40fb65d1f68c71b0d7995f0537a90c7e3ca92116"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): app/Actions/Photo/BaseArchive.php:291-300 | app/Actions/Photo/BaseArchive.php:401-410 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Photo/BaseArchive.php:291\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/BaseArchive.php"},"region":{"startLine":291}}}],"partialFingerprints":{"codehealthFindingId/v1":"04ea1b05bfab808f32dbef5c65877187fefb9ba94627af519f370453b7723bda"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 2): app/Actions/Statistics/Spaces.php:84-93 | app/Actions/Statistics/Spaces.php:204-212 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Statistics/Spaces.php:204\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Statistics/Spaces.php"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"a238fc8dc0efc070422ee6ebf659e2a360b5282187d1b5050863f4dbf09e2b5c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): app/Actions/Statistics/Spaces.php:195-204 | app/Actions/Statistics/Spaces.php:330-339 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Statistics/Spaces.php:195\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Statistics/Spaces.php"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"aff0de980b261231e8b71c3848bd2d833360c9b6ba01f87b9fe9ddfa5e59db42"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u201310 lines \u00D7 2): app/Actions/Statistics/Spaces.php:271-280 | app/Actions/Statistics/Spaces.php:322-329 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Statistics/Spaces.php:271\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Statistics/Spaces.php"},"region":{"startLine":271}}}],"partialFingerprints":{"codehealthFindingId/v1":"97a42b1bd891a4cd1c07d880245247d67bcfaedd9bcce6cb13d1ea4091f3c203"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): app/Console/Commands/ImageProcessing/MoveToS3.php:66-75 | app/Console/Commands/ImageProcessing/TrackS3Migrate.php:68-77 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Console/Commands/ImageProcessing/MoveToS3.php:66\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060app/Console/Commands/ImageProcessing/MoveToS3.php:65\u0060 calls \u0060whereNot\u0060 and \u0060app/Console/Commands/ImageProcessing/TrackS3Migrate.php:67\u0060 does not \u2014 after which the two agree again for 4 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/ImageProcessing/MoveToS3.php"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b740603d3cca704c7cce9069390b5525234a01cde9cf8bb44a48f5a8fdbfa19"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php:309-318 | app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php:331-340 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php:309\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php"},"region":{"startLine":309}}}],"partialFingerprints":{"codehealthFindingId/v1":"a72884a64635d8d0d91eda377e8016d6d2ab3a5b18d35a4c704824bbfc39ddf1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u201310 lines \u00D7 2): app/Http/Resources/GalleryConfigs/LandingPageResource.php:191-198 | app/Http/Resources/GalleryConfigs/LandingPageResource.php:325-334 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/GalleryConfigs/LandingPageResource.php"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f9ceb44e41411eec243e1c8fcd20b0198e34e9216cae3eb99551f2f4ad3ac98"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 2): app/Image/Handlers/GoogleMotionPictureHandler.php:105-113 | app/Image/Handlers/VideoHandler.php:59-68 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Image/Handlers/GoogleMotionPictureHandler.php:105\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060app/Image/Handlers/GoogleMotionPictureHandler.php:113\u0060 calls \u0060MediaFileOperationException\u0060 and \u0060app/Image/Handlers/VideoHandler.php:68\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Image/Handlers/GoogleMotionPictureHandler.php"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d01058b962f8195f01e60c295da6f47bb9db9a2d85fe1fcb1351e43bc72f7ca"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): app/Policies/AlbumPolicy.php:857-866 | app/Policies/PhotoPolicy.php:405-414 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Policies/AlbumPolicy.php"},"region":{"startLine":857}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e280b3cdec0ccc0ea3733ccbc474bf3b167de85760cdea37299c113bcda9727"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u20139 lines \u00D7 5): app/Exceptions/Handlers/AccessDBDenied.php:46-53 | app/Exceptions/Handlers/AdminSetterHandler.php:61-69 | app/Exceptions/Handlers/InstallationHandler.php:61-69 | app/Exceptions/Handlers/MigrationHandler.php:61-68 | app/Exceptions/Handlers/NoEncryptionKey.php:46-53 \u2014 before extracting anything, compare \u0060app/Exceptions/Handlers/AccessDBDenied.php\u0060 and \u0060app/Exceptions/Handlers/NoEncryptionKey.php\u0060 as WHOLE FILES: 83% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Exceptions/Handlers/AdminSetterHandler.php:61\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060app/Exceptions/Handlers/AdminSetterHandler.php:78\u0060 calls \u0060request\u0060, \u0060routeIs\u0060, \u0060renderLegacyInstallerError\u0060 and \u0060app/Exceptions/Handlers/InstallationHandler.php:71\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Exceptions/Handlers/AccessDBDenied.php"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e4a08eb7caaf2a02379c430be5e35a95dd3f68116456a4307926975a7b99150"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 5): app/SmartAlbums/FiveStarsAlbum.php:56-64 | app/SmartAlbums/FourStarsAlbum.php:57-65 | app/SmartAlbums/ThreeStarsAlbum.php:57-65 | app/SmartAlbums/TwoStarsAlbum.php:59-67 | app/SmartAlbums/UnratedAlbum.php:56-64 \u2014 before extracting anything, compare \u0060app/SmartAlbums/FiveStarsAlbum.php\u0060 and \u0060app/SmartAlbums/FourStarsAlbum.php\u0060 as WHOLE FILES: 84% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/SmartAlbums/FiveStarsAlbum.php:56\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/SmartAlbums/FiveStarsAlbum.php"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"a11de7bf20e0dbb85ad2310fa2020efd74f367275165c75cd9f3d995402c24e8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): app/Actions/Renamer/PreviewAlbums.php:56-64 | app/Actions/Renamer/PreviewPhotos.php:64-72 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Renamer/PreviewAlbums.php:56\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Renamer/PreviewAlbums.php"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"9623466811493cb7a9c2ec63e3298c94e574c851802963ca196f061f56442eb9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): app/Console/Commands/RescanFailedFaces.php:73-81 | app/Console/Commands/ScanFaces.php:60-68 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Console/Commands/RescanFailedFaces.php:73\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RescanFailedFaces.php"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"5efac5f877b5a488cc035bd74c237a532ee741d9931196772056fae9023ff54e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): app/Http/Controllers/AiVision/PersonClaimController.php:40-48 | app/Http/Controllers/AiVision/SelfieClaimController.php:84-92 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/AiVision/PersonClaimController.php"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"684afbacd18ed345c16c19afc665984633319c6870d5e10a928ced9351e46d15"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u20139 lines \u00D7 2): app/Jobs/ExtractColoursJob.php:51-59 | app/Jobs/GeodecodeLocationJob.php:46-53 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/ExtractColoursJob.php"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e919ebd1abd0a4cb7cc1de8230255db2bcef38c2aa18873b5c3a989034795b6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): app/Relations/HasManyBidirectionally.php:58-66 | app/Relations/HasManySizeVariants.php:112-121 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Relations/HasManyBidirectionally.php:58\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Relations/HasManyBidirectionally.php"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee483391f70e110eb925d6bc28bacfe6458611bbe9f8e4d923cdab6946797950"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 5): app/Actions/Tag/DeleteTag.php:45-52 | app/Actions/Tag/DeleteTag.php:57-64 | app/Actions/Tag/MergeTag.php:73-81 | app/Actions/Tag/MergeTag.php:119-127 | app/Actions/Tag/MergeTag.php:171-179 \u2014 there are 5 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 5 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Tag/DeleteTag.php"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f066c45c6f7912004ab68bb90a9c90567268c468c7b4f658221ffd427bc48b7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 4): app/Actions/Statistics/Spaces.php:195-202 | app/Actions/Statistics/Spaces.php:263-270 | app/Actions/Statistics/Spaces.php:330-337 | app/Actions/Statistics/Spaces.php:379-386 \u2014 all 4 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Statistics/Spaces.php"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad1c66cd82724e84dbb05e68474150118b75f59fd7646c5bc4d48492b33df163"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Actions/Album/Delete.php:134-141 | app/Actions/Album/Delete.php:160-167 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/Delete.php"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f6dbb31d977d254309d96bc74d6f78f09b4674f787713705a654b9aa3bcd4c8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Actions/Import/Pipes/DeleteMissingAlbums.php:152-159 | app/Actions/Import/Pipes/DeleteMissingPhotos.php:160-168 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Note first that the copies are not typed on the same thing: \u0060Delete\u0060 names \u0060App\\Actions\\Album\\Delete\u0060 in one and \u0060App\\Actions\\Photo\\Delete\u0060 in another \u2014 different types that share a simple name, which is why the text matched. A single extracted unit cannot be given a parameter type that fits both, so unifying those types (or introducing a shared abstraction over them) is the step that has to come BEFORE the extraction above; if they are deliberately separate, the duplication is the price of that separation and the honest resolution is to record the decision rather than to extract."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Import/Pipes/DeleteMissingAlbums.php"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"15d98e3b651733e8fe312fd80766451be14a95eed6525a90a15a8c8777c5ec29"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Http/Controllers/Admin/LandingFeaturedItemController.php:75-82 | app/Http/Controllers/Admin/LandingLinkController.php:75-82 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Controllers/Admin/LandingFeaturedItemController.php:75\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Admin/LandingFeaturedItemController.php"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a421b0ca1f9edce37f5e938feb1e8d661037d8b6211ca620b7f56fc4a502c47"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 2): app/Http/Controllers/Gallery/AlbumListing/AlbumChildrenController.php:108-114 | app/Http/Controllers/Gallery/AlbumListing/AlbumRootController.php:280-287 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Gallery/AlbumListing/AlbumChildrenController.php"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"5eae5609e4105d46df7e50a63a77e4041118abbf4666f687926977bffd8c5d14"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Http/Controllers/Gallery/MapListingController.php:52-60 | app/Http/Controllers/Gallery/MapListingController.php:82-89 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Gallery/MapListingController.php"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"70c85054456e176a26c1d6ac493b8064208bf3e149d7af3072227ce7e0e0903b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Http/Resources/Models/HeadPersonAlbumResource.php:62-69 | app/Http/Resources/Models/HeadTagAlbumResource.php:60-67 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/HeadPersonAlbumResource.php"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"400386ad0c96383f767d3cbfbfc28ecf2e42fab647edbaaf70ea90b50db05e47"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Image/SizeVariantDimensionHelpers.php:106-113 | app/Image/SizeVariantDimensionHelpers.php:123-130 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Image/SizeVariantDimensionHelpers.php:106\u0060 it runs out through the closing brace of the declaration holding it \u2014 the window is that declaration\u0027s tail, not a fragment that begins part-way through something, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Image/SizeVariantDimensionHelpers.php"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"904c31ce8d6feae55af2b49f398647a4871bb61d98e8f1f652f1eb517776b8f5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Jobs/UploadSizeVariantToS3Job.php:39-46 | app/Jobs/WatermarkerJob.php:55-62 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/UploadSizeVariantToS3Job.php"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8304bf8a359936a8b376731309f54716533a16f67bf7217c38337d1d77776e7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Repositories/AlbumRepository.php:122-129 | app/Repositories/AlbumRepository.php:222-229 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Repositories/AlbumRepository.php"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"e79ec1dc940210071c87509d57a46d0eaba8a9cfe6b6bf6db10f9fe463386393"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): app/Actions/Import/Pipes/DeleteMissingAlbums.php:133-139 | app/Actions/Import/Pipes/DeleteMissingPhotos.php:141-147 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Import/Pipes/DeleteMissingAlbums.php"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f06ff161f946da2535404241a9ccc8eadef472d6f2e0fc067119280f9ebb3d1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): app/Actions/Photo/Pipes/Standalone/PlacePhoto.php:82-88 | app/Actions/Photo/Pipes/VideoPartner/PlaceVideo.php:82-88 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/Pipes/Standalone/PlacePhoto.php"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a31c7d8736e4392d4bbe105b264607b13464ca74b8639914fe3b9f6cf7ec2d7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): app/Http/Requests/Face/AssignFaceRequest.php:43-52 | app/Http/Requests/Face/BatchAssignFacesRequest.php:46-52 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/Face/AssignFaceRequest.php:43\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Face/AssignFaceRequest.php"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fa01a55ddc594681eefe88148337f01e26b42f13f47ca2ab7c29cc5a2a062d8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): app/Http/Requests/Search/GetSearchRequest.php:79-85 | app/Http/Requests/Search/GetSearchV3Request.php:116-122 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/Search/GetSearchRequest.php:79\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Search/GetSearchRequest.php"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f3d5c2c0a8c96c7c44ecb219b437b4eef7aa42d140ff2e3760f4dd4b8a7540c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): app/Http/Resources/Search/ResultsResource.php:57-63 | app/Http/Resources/Timeline/TimelineResource.php:50-56 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Search/ResultsResource.php"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b1847847548cb4712d7ff25cc8f2e58e5607c3abf0383697f777187a297b578"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): app/Http/Resources/Flow/FlowResource.php:44-49 | app/Http/Resources/Search/ResultsResource.php:58-63 | app/Http/Resources/Timeline/TimelineResource.php:51-56 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Flow/FlowResource.php"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"438f2a38d9e6a3c68d76a782464eb380c037cdc71595e5d64140b60c12dff328"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): app/Actions/Search/Strategies/Album/AlbumTagStrategy.php:35-40 | app/Actions/Search/Strategies/TagStrategy.php:31-36 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Actions/Search/Strategies/Album/AlbumTagStrategy.php:35\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Search/Strategies/Album/AlbumTagStrategy.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"db0943fea509451f29c243d25bd106dcbdbc10b67688c2331b82824319025096"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): app/Actions/Tag/ListTags.php:62-67 | app/Actions/Tag/ListTags.php:69-74 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Tag/ListTags.php"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"1063f6ea8f7f1a350ca1eb48300f3b8709b6d898686e7afd506b42567bf44440"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): app/Http/Requests/ShopManagement/PrintSize/CreatePrintSizeRequest.php:57-62 | app/Http/Requests/ShopManagement/PrintSize/UpdatePrintSizeRequest.php:61-66 \u2014 before extracting anything, compare \u0060app/Http/Requests/ShopManagement/PrintSize/CreatePrintSizeRequest.php\u0060 and \u0060app/Http/Requests/ShopManagement/PrintSize/UpdatePrintSizeRequest.php\u0060 as WHOLE FILES: 95% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060app/Http/Requests/ShopManagement/PrintSize/UpdatePrintSizeRequest.php:60\u0060 calls \u0060findOrFail\u0060 and \u0060app/Http/Requests/ShopManagement/PrintSize/CreatePrintSizeRequest.php:56\u0060 does not \u2014 after which the two agree again for 4 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/ShopManagement/PrintSize/CreatePrintSizeRequest.php"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"a153c30c4040f26e31203b76a7869061ae38281429f233832a22d683bae61a98"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): app/Http/Requests/Traits/Authorize/AuthorizeCanMergeAlbumsTrait.php:32-37 | app/Http/Requests/Traits/Authorize/AuthorizeCanMoveAlbumsTrait.php:31-36 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/Authorize/AuthorizeCanMergeAlbumsTrait.php"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"6382a41e27c69c6c49c941f0550b3069e7948eac6b78d4a2ace1937c67151593"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): app/Http/Resources/Traits/HasHeaderUrl.php:84-89 | app/Http/Resources/Traits/HasHeaderUrl.php:98-103 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Resources/Traits/HasHeaderUrl.php:84\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Traits/HasHeaderUrl.php"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"1dc0143d4e9d88e6dca8ab2a541609b69d776be42f2ebb97509972ceb7219824"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): app/Jobs/UploadSizeVariantToS3Job.php:69-74 | app/Jobs/WatermarkerJob.php:98-103 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Jobs/UploadSizeVariantToS3Job.php:69\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/UploadSizeVariantToS3Job.php"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"64ded985b56e656d90505b888061d907afda66d2a48661be8a76f7ea6ef27b3b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (37 lines \u00D7 2): app/Http/Requests/Album/GetAlbumChildrenDataRequest.php:44-80 | app/Http/Requests/Album/GetAlbumChildrenRightsRequest.php:41-77 \u2014 before extracting anything, compare \u0060app/Http/Requests/Album/GetAlbumChildrenDataRequest.php\u0060 and \u0060app/Http/Requests/Album/GetAlbumChildrenRightsRequest.php\u0060 as WHOLE FILES: 86% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/Album/GetAlbumChildrenDataRequest.php:44\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Album/GetAlbumChildrenDataRequest.php"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"72e18d728b5a259d4519ecfdd3b53ad73968cf78b79bc4003c80830ad9821673"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): app/Http/Requests/LandingFeaturedItem/DestroyLandingFeaturedItemRequest.php:23-41 | app/Http/Requests/LandingFeaturedItem/ShowLandingFeaturedItemRequest.php:23-41 \u2014 before extracting anything, compare \u0060app/Http/Requests/LandingFeaturedItem/DestroyLandingFeaturedItemRequest.php\u0060 and \u0060app/Http/Requests/LandingFeaturedItem/ShowLandingFeaturedItemRequest.php\u0060 as WHOLE FILES: 95% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/LandingFeaturedItem/DestroyLandingFeaturedItemRequest.php:23\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/LandingFeaturedItem/DestroyLandingFeaturedItemRequest.php"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"2cb17447fc91035d9f2c30354e1cb9db2a5765634972507282447be1e52ab3cf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): app/Http/Requests/LandingFeaturedItem/PatchLandingFeaturedItemRequest.php:26-52 | app/Http/Requests/LandingFeaturedItem/UpdateLandingFeaturedItemRequest.php:26-50 \u2014 before extracting anything, compare \u0060app/Http/Requests/LandingFeaturedItem/PatchLandingFeaturedItemRequest.php\u0060 and \u0060app/Http/Requests/LandingFeaturedItem/UpdateLandingFeaturedItemRequest.php\u0060 as WHOLE FILES: 90% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/LandingFeaturedItem/PatchLandingFeaturedItemRequest.php:26\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/LandingFeaturedItem/PatchLandingFeaturedItemRequest.php"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8bf5ff0658292d0df223a8eae40d03a975d58f8fbf9d5bb3bb9de2eca647dfd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): app/Http/Requests/Map/GetMapBucketsRequest.php:37-60 | app/Http/Requests/Map/GetMapPhotosRequest.php:36-59 \u2014 before extracting anything, compare \u0060app/Http/Requests/Map/GetMapBucketsRequest.php\u0060 and \u0060app/Http/Requests/Map/GetMapPhotosRequest.php\u0060 as WHOLE FILES: 88% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/Map/GetMapBucketsRequest.php:37\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Map/GetMapBucketsRequest.php"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"033146ed9e85623283ff349584506704b4469e2fa6de8f7efe96c98f6c1fa225"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): app/Http/Requests/Moderation/ApproveModerationRequest.php:30-53 | app/Http/Requests/Nsfw/DeleteNsfwFindingsByPhotosRequest.php:30-53 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/Moderation/ApproveModerationRequest.php:30\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Moderation/ApproveModerationRequest.php"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b76fd8a6bf76183ee7f988edd7bbf667764524a7379002ae8f8df1a511c7bd5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): app/Http/Requests/Moderation/GetModerationPhotoHistoryRequest.php:27-46 | app/Http/Requests/Moderation/GetModerationPhotoRequest.php:29-48 \u2014 before extracting anything, compare \u0060app/Http/Requests/Moderation/GetModerationPhotoHistoryRequest.php\u0060 and \u0060app/Http/Requests/Moderation/GetModerationPhotoRequest.php\u0060 as WHOLE FILES: 89% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/Moderation/GetModerationPhotoHistoryRequest.php:27\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Moderation/GetModerationPhotoHistoryRequest.php"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"18d98b3f3292a091b5467f357750dd9fa1503ae83587a957973140308519ce42"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (30 lines \u00D7 2): app/Http/Requests/Statistics/SpacePerAlbumRequest.php:35-64 | app/Http/Requests/Statistics/SpaceSizeVariantRequest.php:35-64 \u2014 before extracting anything, compare \u0060app/Http/Requests/Statistics/SpacePerAlbumRequest.php\u0060 and \u0060app/Http/Requests/Statistics/SpaceSizeVariantRequest.php\u0060 as WHOLE FILES: 97% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/Statistics/SpacePerAlbumRequest.php:35\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Statistics/SpacePerAlbumRequest.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"792d0ab68af3ec75dda75ac735f3d22834f3c6ea24571d5829ea86d2000a6124"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 4): app/Http/Requests/Webhook/DestroyWebhookRequest.php:29-56 | app/Http/Requests/Webhook/PatchWebhookRequest.php:35-76 | app/Http/Requests/Webhook/ShowWebhookRequest.php:29-56 | app/Http/Requests/Webhook/UpdateWebhookRequest.php:34-75 \u2014 before extracting anything, compare \u0060app/Http/Requests/Webhook/DestroyWebhookRequest.php\u0060 and \u0060app/Http/Requests/Webhook/PatchWebhookRequest.php\u0060 as WHOLE FILES: 82% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/Webhook/DestroyWebhookRequest.php:29\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Webhook/DestroyWebhookRequest.php"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"52294b02827dfd656414b967fd83f5c876f3bbde6b0fcbe3be764e478d8a25c5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 5): app/Http/Requests/Webhook/DestroyWebhookRequest.php:29-56 | app/Http/Requests/Webhook/PatchWebhookRequest.php:35-76 | app/Http/Requests/Webhook/ShowWebhookRequest.php:29-56 | app/Http/Requests/Webhook/StoreWebhookRequest.php:31-58 | app/Http/Requests/Webhook/UpdateWebhookRequest.php:34-75 \u2014 before extracting anything, compare \u0060app/Http/Requests/Webhook/DestroyWebhookRequest.php\u0060 and \u0060app/Http/Requests/Webhook/PatchWebhookRequest.php\u0060 as WHOLE FILES: 82% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Http/Requests/Webhook/DestroyWebhookRequest.php:29\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Webhook/DestroyWebhookRequest.php"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1465d82cbcaff261b46a317e3c387b05143b7953fbce3d5235ef89a193d53b0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): app/Legacy/BaseConfigMigration.php:37-48 | app/Models/Extensions/BaseConfigMigration.php:22-33 | app/Models/Extensions/BaseConfigMigrationReversed.php:22-33 \u2014 before extracting anything, compare \u0060app/Models/Extensions/BaseConfigMigration.php\u0060 and \u0060app/Models/Extensions/BaseConfigMigrationReversed.php\u0060 as WHOLE FILES: 83% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060app/Legacy/BaseConfigMigration.php:37\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Legacy/BaseConfigMigration.php"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fe5e9274fb1797502ec7e10223de04fe9a4e0fe3032c7f942e455428059bb8f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (62 lines \u00D7 2): database/factories/PaletteFactory.php:34-95 | database/factories/RenamerRuleFactory.php:34-126 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060database/factories/PaletteFactory.php:34\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/factories/PaletteFactory.php"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"5229ec505258d129b21176e9f5c62ef31e5b7621975927aee2999d18b5ae05a8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 3): database/factories/PurchasablePixelSizeFactory.php:35-60 | database/factories/PurchasablePriceFactory.php:36-77 | database/factories/PurchasablePrintSizeFactory.php:34-58 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060database/factories/PurchasablePixelSizeFactory.php:35\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/factories/PurchasablePixelSizeFactory.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"f223cd905dc8d2e30350e87d137d75e1321f14ca3c84492aa44f3c8f8d341897"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 3): database/factories/PaletteFactory.php:34-95 | database/factories/RenamerRuleFactory.php:34-126 | database/factories/StatisticsFactory.php:33-60 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060database/factories/PaletteFactory.php:34\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/factories/PaletteFactory.php"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8f0f161dd180379ab62b129e4b43d25c87bbba71aa202d36c5ad4f2d223f29f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Actions/Album/BaseArchive.php:83-91 | app/Actions/Photo/BaseArchive.php:77-84 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/BaseArchive.php"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa7af2d6a34febe8e682debea4d0a5fcfd1208df0f6b9773f3754f25de98021d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): app/Actions/Album/SetProtectionPolicy.php:86-91 | app/Http/Controllers/Gallery/AlbumController.php:434-439 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/SetProtectionPolicy.php"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"d11dd289bcb01aa6575062aaaa04f51e9cd4ebba49180cdd46a8150c0e31cf0d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Actions/Diagnostics/Pipes/Checks/OpCacheCheck.php:54-61 | app/Assets/Helpers.php:144-151 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Diagnostics/Pipes/Checks/OpCacheCheck.php"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"97900b307e66297dc688458dc138aa992ba568caab17d6ccde1fe5115dca01fd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:157-170 | app/Actions/Search/StructOfArrays/QuerySearchPhotos.php:171-180 \u2014 before extracting anything, compare \u0060app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php\u0060 and \u0060app/Actions/Search/StructOfArrays/QuerySearchPhotos.php\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 102 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"ddd1471e7aa5771b216a82155895473a5b115a4d2d1e2dd8bdded751a517a231"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Console/Commands/RecomputeAlbumSizes.php:41-48 | app/Console/Commands/RecomputeAlbumStats.php:41-48 \u2014 before extracting anything, compare \u0060app/Console/Commands/RecomputeAlbumSizes.php\u0060 and \u0060app/Console/Commands/RecomputeAlbumStats.php\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumSizes.php"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"3764938d2b47015c2eeab7d30c8d2ffac9cce74845a97b47773a8dd1d2ad2a6c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): app/Http/Controllers/Gallery/AlbumListing/AlbumPersonController.php:107-113 | app/Http/Controllers/Gallery/AlbumListing/AlbumPinnedController.php:106-112 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Gallery/AlbumListing/AlbumPersonController.php"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"fcd721e94ae872e9f027702e9fc7a66dc7d5289b84476bf692cb143d9edcca43"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): app/Http/Requests/Album/GetAlbumHeadRequest.php:31-45 | app/Http/Requests/Album/GetAlbumRequest.php:31-45 \u2014 before extracting anything, compare \u0060app/Http/Requests/Album/GetAlbumHeadRequest.php\u0060 and \u0060app/Http/Requests/Album/GetAlbumRequest.php\u0060 as WHOLE FILES: 95% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Album/GetAlbumHeadRequest.php"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"e79c8c5b85ba988811b32d69f6ddba3a6a7a9dc75fda1c773e96b14acab181a3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Http/Requests/Renamer/DeleteRenamerRuleRequest.php:28-35 | app/Http/Requests/Renamer/UpdateRenamerRuleRequest.php:44-51 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Renamer/DeleteRenamerRuleRequest.php"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b127f6c9676a13dc464ed366137cc1cb8a6375ff2e436939f09054b055c54ff"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): app/Http/Requests/Search/GetSearchRequest.php:46-50 | app/Http/Requests/Search/InitSearchRequest.php:30-34 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Search/GetSearchRequest.php"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e218c2f0e2776a9b2faff22b1636433d3d0d58e8a05aefebb02a2d1c06058aa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 11): app/Http/Requests/ShopManagement/DeletePurchasablesRequest.php:28-33 | app/Http/Requests/ShopManagement/ListPurchasablesRequest.php:28-33 | app/Http/Requests/ShopManagement/PixelSize/CreatePixelSizeRequest.php:27-32 | app/Http/Requests/ShopManagement/PixelSize/DeletePixelSizeRequest.php:27-32 | app/Http/Requests/ShopManagement/PixelSize/UpdatePixelSizeRequest.php:29-34 | app/Http/Requests/ShopManagement/PrintSize/CreatePrintSizeRequest.php:29-34 | app/Http/Requests/ShopManagement/PrintSize/DeletePrintSizeRequest.php:27-32 | app/Http/Requests/ShopManagement/PrintSize/UpdatePrintSizeRequest.php:31-36 | app/Http/Requests/ShopManagement/PurchasableAlbumRequest.php:47-52 | app/Http/Requests/ShopManagement/PurchasablePhotoRequest.php:53-58 | app/Http/Requests/ShopManagement/UpdatePurchasablePriceRequest.php:44-49 \u2014 before extracting anything, compare \u0060app/Http/Requests/ShopManagement/PixelSize/CreatePixelSizeRequest.php\u0060 and \u0060app/Http/Requests/ShopManagement/PixelSize/UpdatePixelSizeRequest.php\u0060 as WHOLE FILES: 95% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/ShopManagement/DeletePurchasablesRequest.php"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d1f54a07e99763dd15d9d8c5be547d189b88736808a1fddd7ef0b3933de45af"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): app/Http/Requests/Timeline/GetTimelineRequest.php:21-25 | app/Http/Requests/Timeline/IdOrDatedTimelineRequest.php:51-55 \u2014 before extracting anything, compare \u0060app/Http/Requests/Timeline/GetTimelineRequest.php\u0060 and \u0060app/Http/Requests/Timeline/IdOrDatedTimelineRequest.php\u0060 as WHOLE FILES: 82% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Timeline/GetTimelineRequest.php"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"03d21de69b7083ecaab54d83301d2b8c342e0cd38087959e3a3ab391fe7ba2b6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Relations/HasManyPhotosByPerson.php:89-96 | app/Relations/HasManyPhotosByTag.php:194-201 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Relations/HasManyPhotosByPerson.php"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"810fdec6dd6de870b44e514d1e224061e9180f65c04d99df69eec11204264453"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): app/Actions/Import/Pipes/DeleteMissingAlbums.php:35-44 | app/Actions/Import/Pipes/DeleteMissingPhotos.php:36-45 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. Note first that the copies are not typed on the same thing: \u0060Delete\u0060 names \u0060App\\Actions\\Album\\Delete\u0060 in one and \u0060App\\Actions\\Photo\\Delete\u0060 in another \u2014 different types that share a simple name, which is why the text matched. A single extracted unit cannot be given a parameter type that fits both, so unifying those types (or introducing a shared abstraction over them) is the step that has to come BEFORE the extraction above; if they are deliberately separate, the duplication is the price of that separation and the honest resolution is to record the decision rather than to extract."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Import/Pipes/DeleteMissingAlbums.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c1a8859e45216e08c9ad8f32bd6e0020309055d2c0e3f8eac5e8ad8c3381afc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 6): app/Http/Controllers/Admin/LandingFeaturedItemController.php:51-55 | app/Http/Controllers/Admin/LandingFeaturedItemController.php:60-64 | app/Http/Controllers/Admin/LandingLinkController.php:51-55 | app/Http/Controllers/Admin/LandingLinkController.php:60-64 | app/Http/Controllers/Admin/WebhookController.php:66-71 | app/Http/Controllers/Admin/WebhookController.php:79-84 \u2014 there are 6 copies across 3 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 6 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Admin/LandingFeaturedItemController.php"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5b8146f355b337d6d05edb733874c91dd82b12f7e5e2343094d4aed3120dc31"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): app/Http/Requests/ShopManagement/PixelSize/DeletePixelSizeRequest.php:50-54 | app/Http/Requests/ShopManagement/PrintSize/DeletePrintSizeRequest.php:50-54 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/ShopManagement/PixelSize/DeletePixelSizeRequest.php"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e5495a29a2a2f12d7d87154e37b40b48fcb81d0be1c058589f5367ad41bf374"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): app/Http/Requests/Traits/Authorize/AuthorizeCanEditPhotosTrait.php:26-32 | app/Http/Requests/Traits/Authorize/AuthorizeCanHighlightPhotosTrait.php:26-32 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/Authorize/AuthorizeCanEditPhotosTrait.php"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc29e0f49c04261f164e19ef6b4ee055b59691b086a6e99e18f596098d9fcde1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): app/Jobs/RecomputeAlbumPhotoBucketsJob.php:60-65 | app/Jobs/RecomputeChildAlbumBucketsJob.php:64-70 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputeAlbumPhotoBucketsJob.php"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bd9b59b1604e3221cca7c853554843d21b952ab7986153fbb0ef81bd8085c4c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Listeners/RecomputeAlbumSizeOnAlbumChange.php:53-60 | app/Listeners/RecomputeAlbumStatsOnAlbumChange.php:44-51 \u2014 before extracting anything, compare \u0060app/Listeners/RecomputeAlbumSizeOnAlbumChange.php\u0060 and \u0060app/Listeners/RecomputeAlbumStatsOnAlbumChange.php\u0060 as WHOLE FILES: 86% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 1 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Listeners/RecomputeAlbumSizeOnAlbumChange.php"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc32ad211fedc771d58d35c8092a7557d450cbd280f837dbbe181f6e49fc97fc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): app/Models/Album.php:650-657 | app/Models/BaseAlbumImpl.php:316-323 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Album.php"},"region":{"startLine":650}}}],"partialFingerprints":{"codehealthFindingId/v1":"154687a941374e3b0dc296e4e4c6ff771df363b577974378cf6e8f4fbbf2b2ee"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): app/Models/LandingFeaturedItem.php:60-66 | app/Models/LandingLink.php:72-78 | app/Models/Webhook.php:103-109 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/LandingFeaturedItem.php"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"d049f1ff458dd879da3e569644f488728ece16dcbb690b40b934c6383c772daf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): app/Models/User.php:283-288 | app/Models/UserGroup.php:93-98 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/User.php"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"1eb61d338d4f8c4decfbc1613c085c6de1e27dbf1ca6e9e17d659c210b22541b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): app/Rules/AlbumIDListRule.php:24-34 | app/Rules/RandomIDListRule.php:23-33 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Rules/AlbumIDListRule.php"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"8176e2375d6d5651af78941c4e0b6deea66dca4b861d19f4c590629c12d2820c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): app/Services/AlbumBucketComputer.php:42-48 | app/Services/PhotoBucketComputer.php:46-52 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/AlbumBucketComputer.php"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"9768da3f67a28c3642845bc125cafdc67801722ae2fd21361313bce15234d539"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): app/SmartAlbums/MyBestPicturesAlbum.php:38-43 | app/SmartAlbums/MyRatedPicturesAlbum.php:34-39 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/SmartAlbums/MyBestPicturesAlbum.php"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfefa8d4e84643d99689346c370029a46c4e4768028b01c6a1b4bc104c1ef07c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): database/factories/AlbumFactory.php:86-90 | database/factories/TagAlbumFactory.php:70-74 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/factories/AlbumFactory.php"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9a8ee6868f8939298c3678ef83075a03d4cd12621a440e85c659671a9dcd1db"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): database/factories/PhotoFactory.php:140-147 | database/factories/TagAlbumFactory.php:54-61 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/factories/PhotoFactory.php"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3dd543ae96974d82fdf6f15871b3211bba4164d0d26884fd2bc20cc5eb67bb2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php:68-72 | app/Actions/Search/StructOfArrays/QuerySearchPhotos.php:72-76 \u2014 before extracting anything, compare \u0060app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php\u0060 and \u0060app/Actions/Search/StructOfArrays/QuerySearchPhotos.php\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 102 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"600abb1893822b32d5ff243b441e79981c7c657a5b27c0457c00d1f545a4d6d0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): app/Http/Requests/Renamer/CreateRenamerRuleRequest.php:74-78 | app/Http/Requests/Renamer/UpdateRenamerRuleRequest.php:83-87 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Renamer/CreateRenamerRuleRequest.php"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"d05439e82aaca2d072991cc135a07239b05e4f48e6b5108eab34e6274f0628df"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): app/Metadata/Renamer/Renamer.php:87-91 | app/Metadata/Renamer/Renamer.php:95-99 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Metadata/Renamer/Renamer.php"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e4f10b74f3aea0aa980b5b257e7020bb5315c614ab6599b813e40984961e459"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: Photo (LCOM4 12): Photo\u0027s methods fall into 12 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 12 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Photo.php"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d92806b64fdd908916eedbf3f35b16fa8a6e1699abeb06657bd6e7eade79f09"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: BaseAlbumImpl (LCOM4 8): BaseAlbumImpl\u0027s methods fall into 8 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 8 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/BaseAlbumImpl.php"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"688c92a49ca985f7719f129e04b99dfee2e73a1388a1e17eb87947547eeab6ca"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: OrderService (LCOM4 6): OrderService\u0027s methods fall into 6 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 6 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Shop/OrderService.php"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9f8054b4315846c8c46642bd326bab27145caca125cfc8cefec9d12d43280cd"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: InitConfig (LCOM4 5): InitConfig\u0027s methods fall into 5 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 5 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/GalleryConfigs/InitConfig.php"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"e02272f8dab4dc3006ed14e45ad2ff8adc9421114b5d0a5ba9a38da57367ef33"}},{"ruleId":"D12","level":"warning","message":{"text":"Abandoned package: laragear/webauthn: \u0060laragear/webauthn\u0060 is marked ABANDONED on Packagist, and this repository requires it at \u0060^5.0\u0060 (locked at v5.0.2). An abandoned package receives no further releases \u2014 including security releases. Its maintainer names \u0060laravel/passkeys\u0060 as the replacement. This is a migration, not an upgrade: a newer release of an abandoned package is not a fix."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"eb53842c4c836c809243eb106f5b30c1d9cd16883e266d3e986be79e4828e4e9"}},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"13ec52c3ec25c6381897e9f592b5fb8f41a2bfd295c72ee02d1e99d3ba15ba85"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c73487c871d33e269b1dc3bd3962701c90fc645c69b1d073e39e7cef79cf0d2e"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"35e141e02210d3f656710f8535beb9c880d2152404eca4c6f554038bf5cce8c2"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"88bca998e00a0e99447b3b128621fc5def1f761b5ef5b35c0b750468c86b0352"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: app/Http/Resources/GalleryConfigs/InitConfig.php: app/Http/Resources/GalleryConfigs/InitConfig.php changed 15 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 18 in InitConfig.__construct at line 228. 1 of those changes was a fix/bug commit, and the other 14 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- app/Http/Resources/GalleryConfigs/InitConfig.php\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/GalleryConfigs/InitConfig.php"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca45fce9c40ed3310b0e834a44088ff536ef970935d0d091f4178e8bbe0e39fa"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: app/Actions/Photo/StructOfArrays/QueryPhotoDetails.php: app/Actions/Photo/StructOfArrays/QueryPhotoDetails.php changed 7 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 35 in QueryPhotoDetails.buildResource at line 105. 3 of those changes were fix/bug commits, and the other 4 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- app/Actions/Photo/StructOfArrays/QueryPhotoDetails.php\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoDetails.php"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"cce3319bf4df89cab1b47ebb67a0c7b49315b77c704b203fab13829aad8a80b5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: resources/js/v8/utils/phpDateFormat.ts: resources/js/v8/utils/phpDateFormat.ts changed 3 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 56 in phpDateFormat.phpDateFormat at line 261. 1 of those changes was a fix/bug commit, and the other 2 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/utils/phpDateFormat.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/phpDateFormat.ts"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"440e027fec89463d6ee32b637b1158e221ae01475ffee74bd80ea88de94570cf"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: app/Models/Configs.php: app/Models/Configs.php changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 41 in Configs.sanity at line 98. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- app/Models/Configs.php\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Configs.php"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"e918e872342dc8f442d7ec8bd0cd3d2f3126610106d0d3a8f6ca9250fe6f650a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: resources/js/v8/composables/useAdminTiles.ts: resources/js/v8/composables/useAdminTiles.ts changed 8 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 20 in useAdminTiles.useAdminTiles at line 27. 2 of those changes were fix/bug commits, and the other 6 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/composables/useAdminTiles.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useAdminTiles.ts"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"732badf3ceb1ba685d11692d940599235029ff168c2e760b9e1cfec8d733ff85"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: resources/js/composables/album/dragAndSelect.ts: resources/js/composables/album/dragAndSelect.ts changed 6 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 20 in dragAndSelect.useDragAndSelect.getAlbumBoxesV3 at line 342. 2 of those changes were fix/bug commits, and the other 4 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/composables/album/dragAndSelect.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/dragAndSelect.ts"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"0570236e20dc9c3a75755e3c7df7e05f54ac42f80bbc0f37cf1bfc3d9022b1f3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php: app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php changed 6 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 20 in QueryPhotoRatios.buildResource at line 176. 1 of those changes was a fix/bug commit, and the other 5 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/StructOfArrays/QueryPhotoRatios.php"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5f1b3422247e0fe1f3d12c9dc24ec31e6321dd32a11c345eb315941fd9ddb42"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: resources/js/v8/components/forms/album/AlbumProperties.vue: resources/js/v8/components/forms/album/AlbumProperties.vue changed 6 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 20 in saveAlbum at line 497. 1 of those changes was a fix/bug commit, and the other 5 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/components/forms/album/AlbumProperties.vue\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumProperties.vue"},"region":{"startLine":497}}}],"partialFingerprints":{"codehealthFindingId/v1":"85c0a74baed8e4e9058cb9a6378103819120e713335c7e107596786be5a131e5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: resources/js/stores/AlbumState.ts: resources/js/stores/AlbumState.ts changed 6 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 16 in (anonymous) at line 856. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/stores/AlbumState.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumState.ts"},"region":{"startLine":856}}}],"partialFingerprints":{"codehealthFindingId/v1":"479176c707e26f65eb2d26d812de235bb8adb87d2dc1d56400599d8ad589ced6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: resources/js/v8/components/gallery/timelineModule/TimelineDatesV3.vue: resources/js/v8/components/gallery/timelineModule/TimelineDatesV3.vue changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 22 in (anonymous) at line 319. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/components/gallery/timelineModule/TimelineDatesV3.vue\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/timelineModule/TimelineDatesV3.vue"},"region":{"startLine":319}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a936573e81a895d46ba4c81495d16ae48f615ba58c4c6d303454724f500c6d6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: resources/js/v8/composables/contextMenus/contextMenu.ts: resources/js/v8/composables/contextMenus/contextMenu.ts changed 5 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 17 in contextMenu.useContextMenu.photoMenu at line 107. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/composables/contextMenus/contextMenu.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/contextMenu.ts"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd8d4ff551b4ba834a6d0f32bcd221725160236da7a2e2a9a47e7fc0e839ad07"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: resources/js/v8/composables/spotlight/useSpotlightGalleryActions.ts: resources/js/v8/composables/spotlight/useSpotlightGalleryActions.ts changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 42 in useSpotlightGalleryActions.useSpotlightGalleryActions at line 34. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/composables/spotlight/useSpotlightGalleryActions.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/spotlight/useSpotlightGalleryActions.ts"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"947b6fb5dd1fb7d8b965291a5461e5ef67dcd57a5fe96f0b33e62a8e6e6601bc"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: app/Http/Resources/GalleryConfigs/AlbumConfig.php: app/Http/Resources/GalleryConfigs/AlbumConfig.php changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 20 in AlbumConfig.__construct at line 54. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- app/Http/Resources/GalleryConfigs/AlbumConfig.php\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/GalleryConfigs/AlbumConfig.php"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"3675aee3b4ba1cb061ecf51c1712d0796e331e289f83120a0408ed5d16d244b7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: resources/js/composables/contextMenus/contextMenu.ts: resources/js/composables/contextMenus/contextMenu.ts changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 17 in contextMenu.useContextMenu.photoMenu at line 103. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/composables/contextMenus/contextMenu.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b76f43f571bffcfb280d7dbd18ae1d942ec6d3775d559e74d54eae2ece36319"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: app/Actions/Admin/BulkEditAlbumsAction.php: app/Actions/Admin/BulkEditAlbumsAction.php changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 29 in BulkEditAlbumsAction.do at line 47. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- app/Actions/Admin/BulkEditAlbumsAction.php\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Admin/BulkEditAlbumsAction.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac2c4d47d29b97c7eb877155bd140b7b0386317ada271450ce47f0269573686a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: app/Actions/Photo/Pipes/Shared/HydrateMetadata.php: app/Actions/Photo/Pipes/Shared/HydrateMetadata.php changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 23 in HydrateMetadata.handle at line 34. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- app/Actions/Photo/Pipes/Shared/HydrateMetadata.php\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/Pipes/Shared/HydrateMetadata.php"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8f5e7c821b127c96498392743adec66be626a2f2b8c85072b80a89e00ef3d27"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: resources/js/composables/contextMenus/leftMenu.ts: resources/js/composables/contextMenus/leftMenu.ts changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 23 in leftMenu.useLeftMenu.items at line 66. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/composables/contextMenus/leftMenu.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"73d67472ea56c0576734882d9c7148b5610dbd24c8ce4db6e480e1f891e93315"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: resources/js/v7/components/forms/album/AlbumProperties.vue: resources/js/v7/components/forms/album/AlbumProperties.vue changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 16 in saveAlbum at line 564. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v7/components/forms/album/AlbumProperties.vue\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumProperties.vue"},"region":{"startLine":564}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a71318181b6900ecdf9fd90c4d3064a66cb99e89e966ee9ba0b28e69d718049"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: resources/js/composables/useAdminTiles.ts: resources/js/composables/useAdminTiles.ts changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 15 in useAdminTiles.useAdminTiles at line 25. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/composables/useAdminTiles.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useAdminTiles.ts"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"c62d70cc97b6f842e1028584cdadd88807e9096b3bfc633277e80f27c8ae30fe"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: resources/js/v8/components/drawers/PhotoDetails.vue: resources/js/v8/components/drawers/PhotoDetails.vue changed 8 times in last 90 days and 5 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 8 (its worst body is getModel at line 324), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201CMore fixes on v8: missing data due to StructofArrays and visuals (#4858)\u201D; \u201CFix person attributions (#4802)\u201D; \u201CFix map on first sidebar load (#4761)\u201D; \u201CFix photo ordering on albums (#4685)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/components/drawers/PhotoDetails.vue\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoDetails.vue"},"region":{"startLine":324}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7695a617658b1a49c7d32ac50f271fd37be55a7b89ca08d980e9675706764f5"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: resources/js/v8/components/gallery/photoModule/PhotoBox.vue: resources/js/v8/components/gallery/photoModule/PhotoBox.vue changed 7 times in last 90 days and 4 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 13 (its worst body is onSwipeEnd at line 594), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201CMore fixes on v8: missing data due to StructofArrays and visuals (#4858)\u201D; \u201Cfix(frontend): let the browser pick 1x/2x variants by rendered size (#4823)\u201D; \u201CFix person attributions (#4802)\u201D; \u201CFix missing support for livekit (#4647)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/components/gallery/photoModule/PhotoBox.vue\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoBox.vue"},"region":{"startLine":594}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0a5915bd5abde6e2cfb4ba2a8b82b6c11af112be9d234c1d3d31bf21e5047d6"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: resources/js/v8/utils/adaptPhotoTile.ts: resources/js/v8/utils/adaptPhotoTile.ts changed 6 times in last 90 days and 4 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 7 (its worst body is adaptPhotoTile.mergePhotoDetail at line 171), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201CMore fixes on v8: missing data due to StructofArrays and visuals (#4858)\u201D; \u201CFix unsanized description of photos (#4824)\u201D; \u201CImplement search v3 \u002B fixes search v2 (#4777)\u201D; \u201CFix dock on smart album (#4741)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/utils/adaptPhotoTile.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/adaptPhotoTile.ts"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f2b050b7f4c0182e6d61a5b68c554a792e61c5b654223df2d97ec25d13e505c"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: resources/js/v8/components/gallery/photoModule/PhotoPanel.vue: resources/js/v8/components/gallery/photoModule/PhotoPanel.vue changed 5 times in last 90 days and 3 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 9 (its worst body is scrollTo at line 132), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201Cfix(photo): scroll PDF pages instead of changing photo (#4898)\u201D; \u201CFix dock on smart album (#4741)\u201D; \u201CFix photo ordering on albums (#4685)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/components/gallery/photoModule/PhotoPanel.vue\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoPanel.vue"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c4efd43355ce958bcb033454bd78e6fc4797dea4e6e20a63ee58e768ad329cf"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: resources/js/v8/components/headers/PhotoHeader.vue: resources/js/v8/components/headers/PhotoHeader.vue changed 5 times in last 90 days and 3 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 3 (its worst body is (anonymous) at line 178), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201Cfix(photo): scroll PDF pages instead of changing photo (#4898)\u201D; \u201CFix dock on smart album (#4741)\u201D; \u201CFix photo ordering on albums (#4685)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/components/headers/PhotoHeader.vue\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/PhotoHeader.vue"},"region":{"startLine":178}}}],"partialFingerprints":{"codehealthFindingId/v1":"79d2ffd5a277c5392bb7fd1352898331a15cbeb7faa8d4bdf97e2091a3a10c15"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListViewVirtual.vue: resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListViewVirtual.vue changed 5 times in last 90 days and 3 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 6 (its worst body is (anonymous) at line 175), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201CFix missing padding (#4797)\u201D; \u201CFix display in non-timeline mode (#4738)\u201D; \u201CRefactoring and fixes on API v3 (#4728)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListViewVirtual.vue\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListViewVirtual.vue"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dd9833ddd159ca6189d24f86eee70fc2e56a49c87be3a70035f8c34acad2685"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootGridVirtual.vue: resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootGridVirtual.vue changed 5 times in last 90 days and 3 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 6 (its worst body is (anonymous) at line 212), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201CFix missing padding (#4797)\u201D; \u201CFix display in non-timeline mode (#4738)\u201D; \u201CRefactoring and fixes on API v3 (#4728)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootGridVirtual.vue\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootGridVirtual.vue"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"47dc4d61c6c0e6c4d68ae9f760c57887c117dabeaba6525d5a7eaa23303783e4"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootListViewVirtual.vue: resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootListViewVirtual.vue changed 4 times in last 90 days and 3 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 6 (its worst body is (anonymous) at line 171), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201CFix missing padding (#4797)\u201D; \u201CFix display in non-timeline mode (#4738)\u201D; \u201CRefactoring and fixes on API v3 (#4728)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootListViewVirtual.vue\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootListViewVirtual.vue"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5680b66f201345ac44a7eeda6f0e4bbd46ec93d3cd73ee8f07b8e183bdeb939"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: app/Http/Requests/Photo/UploadPhotoRequest.php: app/Http/Requests/Photo/UploadPhotoRequest.php changed 3 times in last 90 days and 3 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 3 (its worst body is UploadPhotoRequest.processValidatedValues at line 109), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201CFix memory leak when uploading 3000 photos at the same time (#4863)\u201D; \u201CFix replay upload in the same chunk (#4696)\u201D; \u201CFix slipery zip extraction (#4592)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-07-22..2026-10-20, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-07-22 14:55:01 \u002B02:00\u0027 --until=\u00272026-10-20 14:55:01 \u002B02:00\u0027 --full-history --no-merges -- app/Http/Requests/Photo/UploadPhotoRequest.php\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Photo/UploadPhotoRequest.php"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"577cace32defc7dbf7fd940c53a7b8fdc670e2fd81bc7add190e21cb05b83135"}},{"ruleId":"D16","level":"note","message":{"text":"Off-boarding risk: anonymized user #1: If anonymized user #1 becomes unavailable, 169 significant file(s) lose their only recent owner: app/Policies/AlbumQueryPolicy.php, app/Policies/AlbumPolicy.php, app/Services/Cache/CacheKeyProvider.php, routes/api_v2.php, app/Models/Album.php, app/Exceptions/Handler.php, resources/js/v8/utils/phpDateFormat.ts, app/Policies/PhotoPolicy.php (\u002B161 more). Pair on, review, or document these before any departure."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"608aa1a2fc45cb5ad083c95a876686f038b302d26f64db270c49ea70e7120df8"}},{"ruleId":"D16","level":"note","message":{"text":"Further sole-owners (lower concentration): 1 other contributor(s) are each the sole owner of a small amount of code below the off-boarding threshold \u2014 folded into the bus-factor score and metrics (171 single-owned of 620 analysed files in total, counted over production source files of roughly 2,400 bytes or more, excluding vendored, generated and example/demo trees and test files identified by path convention, largest first; 620 of the 2571 production source files in this repository met that bar). They are anonymized user #2 (2 file(s)) \u2014 spread or document their files in the same way, at lower priority than the named off-boarding risks above. The files folded here: resources/js/embed/types.ts, app/Http/Requests/Embed/EmbededRequest.php."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"6eac528f2429e724e1a97ed868f79eefbcf1888dab4af9a9e673429369bb5b2f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // Todo: later create automation that applies formatting on PR (and create a pull request on top if not formatted properly) \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".php-cs-fixer.php"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"6305af6408df8dd7a6e7c9f4a8dbbaa804771acbbfae153fc53a8ba4535c6c64"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: For higher efficiency, ensure that the photos of each child album together with the original size variant are eagerly loaded. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Album/BaseArchive.php"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c600fa0025834a91085e30eb5da1a3ddfe657de08519674f2aa610036fdaa5c"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: Consider to use a modern OO-approach using [\u0060DirectoryIterator\u0060](https://www.php.net/manual/en/class.directoryiterator.php) and [\u0060SplFileInfo\u0060](https://www.php.net/manual/en/class.splfileinfo.php)"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Import/Pipes/BuildTree.php"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0818bafcbecabc1065d8a25ebb6791add3de875838e2ebfaaea465a9b46ec52"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: it is worth wondering if it is the full album that is bought or if it is just a collection of photos \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Shop/BasketService.php"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"282265ee90ad12a005dcd53caf6cf02fa5a2b8ab46401ac62d0428609cc5eb6f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: Fix this line before PR; init needs more parameters \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/ImageProcessing/VideoData.php"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"71277a81b3b097b6a4971b3df610cdfc3eb0963326b8fa12cccce7310b9cdf9f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: remove s3 support here. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Admin/Maintenance/MissingFileSizes.php"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"771e470a7e7a28d683cbfd05a79a3313f720c48055caea0a69847ae822dcd22f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: Investigate later why this string is 24 characters long. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/HeadAlbumResource.php"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4c21ae5983b2011066dc2471877df689a72886ca33b900239e15d4a0015828f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO : already use the prefetched data for photos instead of 2 extra queries? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Traits/HasHeaderUrl.php"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"dec3ea2d1a86fa8bf451a2db4a8d69954efd6b085bc1ed32e1a0050b8dac7851"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: Replace \u0060exif_read_data\u0060 by \u0060\\Safe\\exif_read_data\u0060 after https://github.com/thecodingmachine/safe/issues/215 has been resolved"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Image/Handlers/GdHandler.php"},"region":{"startLine":211}}}],"partialFingerprints":{"codehealthFindingId/v1":"d79bad8fc7f503a86ac7829f7ea3403e0ec673258bccdd32e08f187b94542b6f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: This may fail for files without an extension. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Metadata/Extractor.php"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae7e124e2e5be8b09b59a9105c9fb9218c3ab390d6a4470b78283e1b33d3e336"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: Implement timezone derivation from location data. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Metadata/Extractor.php"},"region":{"startLine":264}}}],"partialFingerprints":{"codehealthFindingId/v1":"abfcbab37d223729c70f36900f6068fa9317f931776ac76795ce5518aa7a3864"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: If we add the suffix \u0022 s\u0022 here, we should also normalize the fraction here. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Metadata/Extractor.php"},"region":{"startLine":481}}}],"partialFingerprints":{"codehealthFindingId/v1":"99be7cd1acb1a9ce799d93b7ebbb4287b80d0aeed88a904d6e29d14c0182558e"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO : FIX TO USE STORAGE FACADE =\u003E uploads may not be in public/uploads \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Metadata/DiskUsage.php"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"8087492d56d4543381b4ff3545bf2894ccef241098bdb4abd095c8cd89418ecd"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO : FIX TO USE STORAGE FACADE =\u003E uploads may not be in public/uploads \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Metadata/DiskUsage.php"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fcec98ac1bded8b78ef03cf0420314f278afe15825fbfb1e96840d278ba20f2"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO : FIX TO USE STORAGE FACADE =\u003E uploads may not be in public/uploads \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Metadata/DiskUsage.php"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"21e494b0cd74ba09cbb1971ad7c74b8bb059fbdbff115a280e62769ac86122c4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: later consider how to handle albums. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/OrderItem.php"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"70162b2e65a68f867068c0a6328d13377558c1a174d279a80a954eb48ee05963"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: move the owner to ACCESS PERMISSIONS so that we do not need to join base_album anymore \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Policies/AlbumQueryPolicy.php"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a938a5ee357c7479f7870802c4aefc6099e9467c9bee5c30ff4fabc587e244c"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: Maybe we should drop this Flysystem disk, because neither the driver nor the root must be changed and hence the whole point of using the Flysystem abstraction is gone. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"config/filesystems.php"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"54495d66aa14cc273c49b2ec328b281cfe2d7036282e4f41c4177d3bedb391e3"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: figure out why this sometimes happens... \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/metrics-service.ts"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a727df6bc66ebdba1583d07561a3ab42277c2b3558df5e66f5f8593ecc7c0c2"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: Those should require admin no ??? \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"routes/api_v2.php"},"region":{"startLine":473}}}],"partialFingerprints":{"codehealthFindingId/v1":"e494e5f4b02a788604bef22cc50ebc6e5eefbdc7926803b9ca2bebca49ca38ae"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: not only the times, but make sure the right arguments are passed, but this is hard to do find with mockery \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Unit/Http/Requests/Album/MoveAlbumsRequestTest.php"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c80f41fbc2408996b84aa6155672e042da4ed40093f7584d9c95d5d2a6d747e"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: refactor the MergeAlbumRequest to use the AlbumFactory or a Repo so that the test can be written without talking to DB \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Unit/Http/Requests/Album/MoveAlbumsRequestTest.php"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"9719c846fa4ccea68887f97247e7c450f5543b6b051c0afe7f78c5c7dcadc8f3"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO:// not only the times, but make sure the right arguments are passed, but this is hard to do find with mockery \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Unit/Http/Requests/Album/MergeAlbumRequestTest.php"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"b20080d707f180ea471a5c428a56de5618067cbfa22a72e34c5ace0ae172522b"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Track (Models \u2192 Http): Track (context Models) is exposed in Http\u0027s public surface via DeleteAlbumTrackRequest.track \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"86d547ea524cac0c508f0767847a9f489685758839b07391150ef13f1ccd4d54"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via GetAlbumBucketsRequest.album \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Album/GetAlbumBucketsRequest.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"e93f153f5dcff500e0e592ac71a4d6c813ebb787d6d7a6145f0b7a3afd0c3ce7"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Track (Models \u2192 Http): Track (context Models) is exposed in Http\u0027s public surface via RenameAlbumTrackRequest.track \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"0a000ab1122001143dd75a645a3f90b1f33e2524fd77474df15f864501861bd8"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via UpdateAlbumRequest.coverPhoto \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Album/UpdateAlbumRequest.php"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"7cc0618a7fc175c440e1f749b9d03594ef53b458e08b25c075b0ea150a93eeff"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via AddAlbumToBasketRequest.album \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c40baa1483e2b1ee1b68706e077cfba71c9d2424289fb6a7cb7f341bcaea81ca"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via AddPhotoToBasketRequest.photo \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"b41caa4275fa9df0240508c00f93750c489746c50d2b0437dd041412e4ab95ed"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via AddPixelItemRequest.photo \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a7faaaa318b49d50a2b9e3da743b6cb4b7ac70cdcb5a509c60042a278078edc2"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PixelSize (Models \u2192 Http): PixelSize (context Models) is exposed in Http\u0027s public surface via AddPixelItemRequest.pixel_size \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"8297a591c32854ca355315ccf29416c4907d51f49a83f360efabd72c7a4de821"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via AddPrintItemRequest.photo \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"38fa704f8b3c4094e64acdfd7dd4104e208deae03bd7188865da35c6b9fff229"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PrintSize (Models \u2192 Http): PrintSize (context Models) is exposed in Http\u0027s public surface via AddPrintItemRequest.print_size \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a59d9c602f2014ae03562f16ada653a8eb0c4075af5732f3e36fee64caf8a44e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Order (Models \u2192 Http): Order (context Models) is exposed in Http\u0027s public surface via GetBasketRequest.basket \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Basket/GetBasketRequest.php"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"48faf72ae1ba1219865dc0b2ca75b0607597bf00b8301cc55cfe9fa59a1fad99"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Purchasable (Models \u2192 Http): Purchasable (context Models) is exposed in Http\u0027s public surface via GetCatalogueSizesRequest.purchasable \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"b331f4b4a177a97ab95fb766ac372ed55bd9f57343277b4f6dcc16a922a12a1a"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Order (Models \u2192 Http): Order (context Models) is exposed in Http\u0027s public surface via CancelRequest.basket \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Checkout/CancelRequest.php"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b25ac6ac48141a2efe0244a1838ed6d6d1d474b3f9e36f45c1f79daae344fb1"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Order (Models \u2192 Http): Order (context Models) is exposed in Http\u0027s public surface via FinalizeRequest.basket \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Checkout/FinalizeRequest.php"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"4397303cca8a3334b5e593cba13bf301a04070433e5bbf8279b9bbe9c50ce93e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ContactMessage (Models \u2192 Http): ContactMessage (context Models) is exposed in Http\u0027s public surface via DeleteContactMessageRequest.contactMessage \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Contact/DeleteContactMessageRequest.php"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ddac11a382703b50354890f4c8383fcdcd15c69a4cc87d353313c975bb97ff4"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ContactMessage (Models \u2192 Http): ContactMessage (context Models) is exposed in Http\u0027s public surface via UpdateContactMessageRequest.contactMessage \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Contact/UpdateContactMessageRequest.php"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0b66301315fbf3785f59f003419e91e9711182d95541993f8c97cc23f67dc89"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via BulkScanRequest.album \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Face/BulkScanRequest.php"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d25e1c4da9d3f22b831bc567c0443c083a76f354a417a350cd69c24d439361c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type SizeVariant (Models \u2192 Http): SizeVariant (context Models) is exposed in Http\u0027s public surface via GetFacePhotoAssetRequest.sizeVariant \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Face/GetFacePhotoAssetRequest.php"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"0615df6e301a5b602470c70d5bdf266e8422c1b3d67bd097c85728e1714a25c9"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via ScanPhotosRequest.album \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Face/ScanPhotosRequest.php"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"07b7be41ec2f53183445427823a4aa95551f4dd093d57f3e59451537126d5ee2"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via FrameRequest.subAlbumRoot \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Frame/FrameRequest.php"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c576492a604d03c5c1411f1098988d9daec5c66d41f99d8457e01e69feba51f"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type LandingFeaturedItem (Models \u2192 Http): LandingFeaturedItem (context Models) is exposed in Http\u0027s public surface via DestroyLandingFeaturedItemRequest.landing_featured_item \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"1d0c4fcc632d0d603b124d6a82e95219a7bdb5940cf6c0983d5ad1f1d5142f48"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type LandingFeaturedItem (Models \u2192 Http): LandingFeaturedItem (context Models) is exposed in Http\u0027s public surface via PatchLandingFeaturedItemRequest.landing_featured_item \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a4304f831b908c6f2884bd7f0b7b98b75dec83773b4dc94836d8a5e79243d439"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type LandingFeaturedItem (Models \u2192 Http): LandingFeaturedItem (context Models) is exposed in Http\u0027s public surface via ShowLandingFeaturedItemRequest.landing_featured_item \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"ba27119538be49ffbac2a907b4909a8a4cc98d585e94d2f1eb500c52ab8f3293"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type LandingFeaturedItem (Models \u2192 Http): LandingFeaturedItem (context Models) is exposed in Http\u0027s public surface via UpdateLandingFeaturedItemRequest.landing_featured_item \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"383bd2582638a23c34ee9cff7179ec68940b4a73dc6af532ac9eb657c0978343"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type LandingLink (Models \u2192 Http): LandingLink (context Models) is exposed in Http\u0027s public surface via DestroyLandingLinkRequest.landing_link \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7e9f5b2539fef3bd4152af6d933ea8c20f4480c991138bcabfc01942da69a52e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type LandingLink (Models \u2192 Http): LandingLink (context Models) is exposed in Http\u0027s public surface via PatchLandingLinkRequest.landing_link \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"455fabf2abeed4a41fb84e2e3fef0c129d52116daa900ab6e657c5e860ae4267"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type LandingLink (Models \u2192 Http): LandingLink (context Models) is exposed in Http\u0027s public surface via ShowLandingLinkRequest.landing_link \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"dac67074fbd9686230a1ad98594cd4f9926882752d4592957e2afde9f4300c42"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type LandingLink (Models \u2192 Http): LandingLink (context Models) is exposed in Http\u0027s public surface via UpdateLandingLinkRequest.landing_link \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"40312988ed52fc0a8e53a353c3ad18d07b74beb0af9ea4bf5227eda728bd93e6"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Order (Models \u2192 Http): Order (context Models) is exposed in Http\u0027s public surface via GetOrderRequest.order \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"9f64c81892c1475cadc8710c6f4ca190f9aedfe36db30b9b6271a9f258ba504b"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Order (Models \u2192 Http): Order (context Models) is exposed in Http\u0027s public surface via MarkAsDeliveredOrderRequest.order \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"59877f9d4eb04b0194cd34d816751a74089fc83698c42f372e7303cc8a8e8862"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Order (Models \u2192 Http): Order (context Models) is exposed in Http\u0027s public surface via MarkAsPaidOrderRequest.order \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"1b2516dafedac89464c0c93fd367045233627321b9621054179f8add7c323703"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type SizeVariant (Models \u2192 Http): SizeVariant (context Models) is exposed in Http\u0027s public surface via GetPhotoAssetRequest.sizeVariant \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Photo/GetPhotoAssetRequest.php"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3412b14f2f47d348e9dd73a4ff5542a0d566f6bdac8c866bbe83dd81b19754c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RenamerRule (Models \u2192 Http): RenamerRule (context Models) is exposed in Http\u0027s public surface via DeleteRenamerRuleRequest.renamer_rule \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"ca29f161c57c786230fb832482397f7ad370a99a63025b538fb8d7fbe02c4f60"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RenamerRule (Models \u2192 Http): RenamerRule (context Models) is exposed in Http\u0027s public surface via UpdateRenamerRuleRequest.renamer_rule \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"4813554a17d3d3179387cad45d6499ac7a7f0faead00ec7df98c2bb5c2711147"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via GetSearchV3Request.origin \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Search/GetSearchV3Request.php"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"2701f0c756e123e1702629135c43b200ab1422f00b0eff285bae8015b3102a21"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PixelSize (Models \u2192 Http): PixelSize (context Models) is exposed in Http\u0027s public surface via DeletePixelSizeRequest.pixel_size \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"39fb34184cdf2704482eec77f6864fc175424201aea048d8b744ac2010cf2273"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PixelSize (Models \u2192 Http): PixelSize (context Models) is exposed in Http\u0027s public surface via UpdatePixelSizeRequest.pixel_size \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7e3d8db4ac1c94a9b215db1ac5c8376dfbd78b5e1b48f7a81246b7678cd38e88"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PrintSize (Models \u2192 Http): PrintSize (context Models) is exposed in Http\u0027s public surface via DeletePrintSizeRequest.print_size \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a9cbca29642bf51e30bfa943d40baff2409caa054b16c278e9702701b3a78fa1"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PrintSize (Models \u2192 Http): PrintSize (context Models) is exposed in Http\u0027s public surface via UpdatePrintSizeRequest.print_size \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f37c7ea029e4339702b625b6413fe4abb1d8fac17bb846f5b658667623674898"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Purchasable (Models \u2192 Http): Purchasable (context Models) is exposed in Http\u0027s public surface via UpdatePurchasablePriceRequest.purchasable \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"14042bf4478d420021bfd0455a38bcc0221d798faa36f3563d33cd35cc398050"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Tag (Models \u2192 Http): Tag (context Models) is exposed in Http\u0027s public surface via MergeTagRequest.destinationTag \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Tags/MergeTagRequest.php"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"e16e6b865eea38b645e4e2c92aff7959ec65318f71cb7c9eca5727677ab1f4a8"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AccessPermission (Models \u2192 Http): AccessPermission (context Models) is exposed in Http\u0027s public surface via HasAccessPermissionTrait.perm \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/HasAccessPermissionTrait.php"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"586148acf98fa1582e876c4834f3a40df3a341986809250a26f28bc98c31ac91"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via HasAlbumTrait.album \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/HasAlbumTrait.php"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7e6b5c61ae2b5ea2255e368ed45a991d62242626bd87d3b09705359bff5109a"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type BaseAlbum (Models \u2192 Http): BaseAlbum (context Models) is exposed in Http\u0027s public surface via HasBaseAlbumTrait.album \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/HasBaseAlbumTrait.php"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d6048c173e67dbafb3d2fb80600a7d63dfb9b63aaa608e323e94e5656014898"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Order (Models \u2192 Http): Order (context Models) is exposed in Http\u0027s public surface via HasBasketTrait.basket \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/HasBasketTrait.php"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"63e12783d610c072f16f667adcb13b5e7e4ecd73e38346c4e91859846e89e9e6"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Face (Models \u2192 Http): Face (context Models) is exposed in Http\u0027s public surface via HasFaceTrait.face \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/HasFaceTrait.php"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"f14146de5f74fcdd27d69cac98edfd1de8d3b9fc687f3dbdcf21f4d03b76584f"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via HasParentAlbumTrait.parent_album \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/HasParentAlbumTrait.php"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"8fe9092abe61655970365bcf27e45bef911042cdeb6909f28fe1a07e3f63c979"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PersonAlbum (Models \u2192 Http): PersonAlbum (context Models) is exposed in Http\u0027s public surface via HasPersonAlbumTrait.album \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/HasPersonAlbumTrait.php"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7b43a6a98603be1cc356c2aaf7c2757d8f534fc83bcf1d2b6b9c1426bae0485"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Person (Models \u2192 Http): Person (context Models) is exposed in Http\u0027s public surface via HasPersonTrait.person \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/HasPersonTrait.php"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"947b15a8ee52ec749df5dfe61ae4b8f997116457a46b7bca30b3a31d2aca8933"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via HasPhotoTrait.photo \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/HasPhotoTrait.php"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"4995a95be2c7b751acf4fe2a31a6376cb7e24f3e179cb5f5db053c1974b8941f"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type TagAlbum (Models \u2192 Http): TagAlbum (context Models) is exposed in Http\u0027s public surface via HasTagAlbumTrait.album \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/HasTagAlbumTrait.php"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"c00e04d1e70cb7a459f031b22c534b1898788892e697a7a0f2616e4dd9b59ae0"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Tag (Models \u2192 Http): Tag (context Models) is exposed in Http\u0027s public surface via HasTagTrait.tag \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/HasTagTrait.php"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"becbe4febd175d4cba3526ea35b66475eb67e89ecf5e37e4322af1fddcd5c3b8"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type UserGroup (Models \u2192 Http): UserGroup (context Models) is exposed in Http\u0027s public surface via HasUserGroupTrait.user_group \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Traits/HasUserGroupTrait.php"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d690cf80e5297bb88eccbc5b775a5caecb87d1239d2a2f41a340d92d3da5060"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Webhook (Models \u2192 Http): Webhook (context Models) is exposed in Http\u0027s public surface via DestroyWebhookRequest.webhook \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e01ea50bff4b55d4a1bee1ef7e0f2158ad0256b86db5baf6833039593801d4d0"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Webhook (Models \u2192 Http): Webhook (context Models) is exposed in Http\u0027s public surface via PatchWebhookRequest.webhook \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"96460b390bc65bbb779e4cd200953b069dc681ffebf8c0c186efed608b937eef"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Webhook (Models \u2192 Http): Webhook (context Models) is exposed in Http\u0027s public surface via ShowWebhookRequest.webhook \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"15ea1e3cee4751b2a096d9372b974fc23abd5b78392d11f39e249723866deeee"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Webhook (Models \u2192 Http): Webhook (context Models) is exposed in Http\u0027s public surface via UpdateWebhookRequest.webhook \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"8dc1cdedc3863ad246ea06cf033089ffed0d980583ae0b44d3dee81824e3c289"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via AlbumTree.FromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Diagnostics/AlbumTree.php"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e679ef5015ee070138edd026acc33bfbe6e9428b63fc6c9e46a566fe25c1d00"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via EmbedAlbumInfo.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Embed/EmbedAlbumInfo.php"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"7da6e1db69c60f1661e319d16973ab4ce5ab691621abeebcf7cd898839f23b8b"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via EmbedAlbumResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Embed/EmbedAlbumResource.php"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"595aef41dfb84c318603dbcbf544bb3c342b4808c33cffaca5baaf63081f218f"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via EmbedAlbumResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Embed/EmbedAlbumResource.php"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"fab6733cc0891791a9d0769a29103b1bf287306f366850b46f42fa9f974718a3"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via EmbedPhotoResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Embed/EmbedPhotoResource.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad8d99d5849ba964bfa1406ff6409a30003a03b00aa8537cfb97efbbd1653395"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via EmbedPhotoResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Embed/EmbedPhotoResource.php"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"75ffc77514c4e47ed158310b71aca0da02dc81355c3c88a43bba258c9f372b8b"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via FlowItemResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Flow/FlowItemResource.php"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"da74d22898a7a16474501ec0501b695d2a613e1bab2171056c48858972c171ad"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via FramePhotoData.fromPhoto \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Frame/FramePhotoData.php"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd218348aed330d21304dc86f088a562f5261b55396bd58feef36c402db182b0"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type LandingLink (Models \u2192 Http): LandingLink (context Models) is exposed in Http\u0027s public surface via LandingLinkEmbedResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/GalleryConfigs/LandingLinkEmbedResource.php"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e404544d56d70649c902e113c37a13437ab6d716cc214d3cf7b9adec97026d7"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AccessPermission (Models \u2192 Http): AccessPermission (context Models) is exposed in Http\u0027s public surface via AccessPermissionResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/AccessPermissionResource.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc2cd7c03d6229983c8fd5be553405f9db79ab6d2c93bb80b6d1cdef617799fb"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Statistics (Models \u2192 Http): Statistics (context Models) is exposed in Http\u0027s public surface via AlbumStatisticsResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/AlbumStatisticsResource.php"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e826251329740491ca8940fc451ef353e03f3e99df2f79e8328f9ce9627fd88"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Palette (Models \u2192 Http): Palette (context Models) is exposed in Http\u0027s public surface via ColourPaletteResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/ColourPaletteResource.php"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7bb5d9b711e43f49deb22e688a8d2e5b4356cc39d74ff77226032a93d5ef779"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Palette (Models \u2192 Http): Palette (context Models) is exposed in Http\u0027s public surface via ColourPaletteResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/ColourPaletteResource.php"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d88f2ffab5bb00ef4c2bd13255388e1c1df6b269079f0ac13480ddc2bc14d05"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ConfigCategory (Models \u2192 Http): ConfigCategory (context Models) is exposed in Http\u0027s public surface via ConfigCategoryResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/ConfigCategoryResource.php"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"25c82c405eb3de8dc88bd852214658835139a58d78399a9c011779756f840f52"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ConfigCategory (Models \u2192 Http): ConfigCategory (context Models) is exposed in Http\u0027s public surface via ConfigCategoryResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/ConfigCategoryResource.php"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"e347876ea8f552fbabff27f5793301a601e3e4e0617b295854543a751d608dce"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Configs (Models \u2192 Http): Configs (context Models) is exposed in Http\u0027s public surface via ConfigResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/ConfigResource.php"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"510702c3de1aefb9fff0ac19f5b4777efd10d24549185e184dd56e296956cc38"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Configs (Models \u2192 Http): Configs (context Models) is exposed in Http\u0027s public surface via ConfigResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/ConfigResource.php"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b28840aee85cca04d5a9b3b14e82820c45383c97d7aa09a46c3d536e811e358"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ContactMessage (Models \u2192 Http): ContactMessage (context Models) is exposed in Http\u0027s public surface via ContactMessageResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/ContactMessageResource.php"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"7950a9f14f227acbd4d5152aedd7e57dfbbab04be498ff7568b6944e14926aad"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Face (Models \u2192 Http): Face (context Models) is exposed in Http\u0027s public surface via FaceResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/FaceResource.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"96f4fb57232e0d020ba5a7e85c0630fafd33e226e1a4729511f0b985f706bbbe"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Face (Models \u2192 Http): Face (context Models) is exposed in Http\u0027s public surface via FaceResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/FaceResource.php"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e884e0e27b82b432e1f5e70d2135f7524f682d69bafc0fb22704fcfde257b3e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type FaceSuggestion (Models \u2192 Http): FaceSuggestion (context Models) is exposed in Http\u0027s public surface via FaceSuggestionResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/FaceSuggestionResource.php"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"5dc09933305477213bba31235a06e5dcb5c1493bcd42b826cd2c876e4aa4a57c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via HeadAlbumResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/HeadAlbumResource.php"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ab38cd7f2cd355216ef0492aa2bd917a8846506d9ea38393450d5a9454522c5"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via HeadAlbumResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/HeadAlbumResource.php"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb0d5c8e8eebfe23efa9e410c0c9d7b18a14d4dd54cd941ccefc3b907cae7638"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PersonAlbum (Models \u2192 Http): PersonAlbum (context Models) is exposed in Http\u0027s public surface via HeadPersonAlbumResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/HeadPersonAlbumResource.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"57358aaf02861d69771852927d1affdb36460de840a24663e301c99f8eaf22d2"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PersonAlbum (Models \u2192 Http): PersonAlbum (context Models) is exposed in Http\u0027s public surface via HeadPersonAlbumResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/HeadPersonAlbumResource.php"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f82d86f3689f41ada33f697e2ad920bec45e5623c847b58897723d1c0bd625c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type TagAlbum (Models \u2192 Http): TagAlbum (context Models) is exposed in Http\u0027s public surface via HeadTagAlbumResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/HeadTagAlbumResource.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"b055c63619de20abd04e2bd48bfb90570a11d6a0360ecc7aa1f9e724ec2609eb"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type TagAlbum (Models \u2192 Http): TagAlbum (context Models) is exposed in Http\u0027s public surface via HeadTagAlbumResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/HeadTagAlbumResource.php"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"716d64e50df7a94be8bc7328ec9b59ce41f9dbe3f2e473a1d9497b31e730bb9e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type JobHistory (Models \u2192 Http): JobHistory (context Models) is exposed in Http\u0027s public surface via JobHistoryResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/JobHistoryResource.php"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"912c1877915d3510643e917d05d8cfb63146f813250e00ea4d5e522637a77cca"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type JobHistory (Models \u2192 Http): JobHistory (context Models) is exposed in Http\u0027s public surface via JobHistoryResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/JobHistoryResource.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"244707d45217f3e9b6f8b7e26c25c3cf9db62f8c20e32d00182eeb2bf214af22"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type LandingFeaturedItem (Models \u2192 Http): LandingFeaturedItem (context Models) is exposed in Http\u0027s public surface via LandingFeaturedItemResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/LandingFeaturedItemResource.php"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"541b5ae3ec64c325e925e3bad9880bf1b76bbc1e41de1b0e941b95bb7aacd273"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type LandingLink (Models \u2192 Http): LandingLink (context Models) is exposed in Http\u0027s public surface via LandingLinkResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/LandingLinkResource.php"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7d85bd33260d3f4ff57b7a73c0e292777146cafd2f10f21627e1892585244f2"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type LiveMetrics (Models \u2192 Http): LiveMetrics (context Models) is exposed in Http\u0027s public surface via LiveMetricsResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/LiveMetricsResource.php"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"f85f8cb81db96d68bb8d228f3c01ae167c17716e4aae18ff65f171948e3f2730"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PhotoModerationEvent (Models \u2192 Http): PhotoModerationEvent (context Models) is exposed in Http\u0027s public surface via ModerationEventResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/ModerationEventResource.php"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8495fc66df8287c9dc38254f7861b8f67de0311286957c5f7e31e746d9afa85"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via ModerationResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/ModerationResource.php"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fb81e0c1f99d8aa58289727654e140c8280524e427dc47eb064e5fbd9d9c5e2"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type NsfwDetection (Models \u2192 Http): NsfwDetection (context Models) is exposed in Http\u0027s public surface via NsfwDetectionResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/NsfwDetectionResource.php"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5f8ccd0cab7a05e7ec74696f58cf63909c4c7e386d9d5370a056c5a9b43c3cf"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via NsfwFindingResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/NsfwFindingResource.php"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc5d18db26e1f2f15dddc906a5848994575cdb0886bced2d54f86af6fcad2f78"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via PanoramaResource.fromPhoto \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/PanoramaResource.php"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"911278152d99bd910c5acecedbe9cd825874e8158fffab1cbdfd86e663beb374"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Person (Models \u2192 Http): Person (context Models) is exposed in Http\u0027s public surface via PersonResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/PersonResource.php"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"f84b8888f83f8d3c1ac2dfe22ffa5ae2d388a6e09e6e5582b2347f3f99d7180b"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Person (Models \u2192 Http): Person (context Models) is exposed in Http\u0027s public surface via PersonResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/PersonResource.php"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"d03563141531bbcd0b2d26621d0182677cad4226d1f8948d4d97fe1612965aed"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Album (Models \u2192 Http): Album (context Models) is exposed in Http\u0027s public surface via PhotoAlbumResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/PhotoAlbumResource.php"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdf37e4e872cebe1e3093662c66eb07dcc4ed2e884720b59d08238253d49b40d"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via PhotoFacesResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/PhotoFacesResource.php"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb636f7af9fc05f778cda232d93328ea09c59aa1a69e26633fe2896071897f9c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via PhotoNsfwDetectionsResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/PhotoNsfwDetectionsResource.php"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9b16f6276106e1fc41b64af501e81207ab7c67bf3a8a7583a7740ca57d1dbe1"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Statistics (Models \u2192 Http): Statistics (context Models) is exposed in Http\u0027s public surface via PhotoRatingResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/PhotoRatingResource.php"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"da34804224faa11b48de12d6be666d71ddfcda8416c8109150deffeb93b79a2d"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via PhotoResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/PhotoResource.php"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"04b864b159dc2fe6620034e189d6339376650286968459ba94c5dbb619298755"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RenamerRule (Models \u2192 Http): RenamerRule (context Models) is exposed in Http\u0027s public surface via RenamerRuleResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/RenamerRuleResource.php"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"55c234ccc8a267968e1b52ca8468f079e8196f7bcec716d2c142ae6760573f7e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RenamerRule (Models \u2192 Http): RenamerRule (context Models) is exposed in Http\u0027s public surface via RenamerRuleResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/RenamerRuleResource.php"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"0be8257c738e58c46fc0df4ea04a6c08f223bb14fc116e99c326a2edf9944817"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type SizeVariant (Models \u2192 Http): SizeVariant (context Models) is exposed in Http\u0027s public surface via SizeVariantResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/SizeVariantResource.php"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c83ddc73a198bffc95589c4235055e14b76dc8026d030eb14496fe1969bf7a0"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via SizeVariantsResouce.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/SizeVariantsResouce.php"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a3cce25b142227545725547c3270a52e7279b8e6208dbaf20329a2d3b78ba83"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Track (Models \u2192 Http): Track (context Models) is exposed in Http\u0027s public surface via TrackResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/TrackResource.php"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"79d3b79bbf1d2518d9ed6451b2724c2b033d14ad71702646ef51c239908d1d9e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type UserGroup (Models \u2192 Http): UserGroup (context Models) is exposed in Http\u0027s public surface via UserGroupResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/UserGroupResource.php"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"67141c81e24479e4bd15fd030c4537e0a951f9edd633d58bd38a1b12dc57c34d"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type BaseAlbum (Models \u2192 Http): BaseAlbum (context Models) is exposed in Http\u0027s public surface via AlbumProtectionPolicy.ofBaseAlbum \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/Utils/AlbumProtectionPolicy.php"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bcd861eafa914b1b60d0e1a19d03dd26f505fcd574ecd63797750e0e986bada"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Person (Models \u2192 Http): Person (context Models) is exposed in Http\u0027s public surface via PersonNameResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/Utils/PersonNameResource.php"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"d742ec3c48d2ac62a174231606f7be62667a5d66d3a355cbf2f4afd24e5e81ac"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via PreComputedPhotoData.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/Utils/PreComputedPhotoData.php"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"d56a825f74d86895d699703f529ae224f1ce2c8fdeb3cfba726f77dc76fa2be8"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via PreformattedPhotoData.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/Utils/PreformattedPhotoData.php"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9fe026e1815a151080fb50ffd49219175ac46072aa90fc8fc059fc42eeab825"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Webhook (Models \u2192 Http): Webhook (context Models) is exposed in Http\u0027s public surface via WebhookResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/WebhookResource.php"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"b87959acc8a1226ca382c326ead1f8c5cb4b0b2e69a9857f02ecfb801f50b46c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Photo (Models \u2192 Http): Photo (context Models) is exposed in Http\u0027s public surface via PhotoRightsResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Rights/PhotoRightsResource.php"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"7dfdc967212b9d48efa0041e6957ce4cb888979d1332687cc932c6a6632c5d58"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type UserGroup (Models \u2192 Http): UserGroup (context Models) is exposed in Http\u0027s public surface via UserGroupRightResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Rights/UserGroupRightResource.php"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e11eee21d7c90428466a6da84e4f43160d4727769933e21cee551d4bac12db2"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Purchasable (Models \u2192 Http): Purchasable (context Models) is exposed in Http\u0027s public surface via CatalogResource.__construct \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Shop/CatalogResource.php"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"4bedac9a76f85904a3533ce870604682bc1524581bd1366d94888bc84ce6a4b2"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Purchasable (Models \u2192 Http): Purchasable (context Models) is exposed in Http\u0027s public surface via EditablePurchasableResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Shop/EditablePurchasableResource.php"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2bfda40c7a1badbc977d42f6fe0fff182cb5cb25c606775ba3182d6622b1695"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type OrderItem (Models \u2192 Http): OrderItem (context Models) is exposed in Http\u0027s public surface via OrderItemResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Shop/OrderItemResource.php"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"ccfe59911546050ea59eef0fa82b239429cc98129a4f0c86bcec4927282fae10"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Order (Models \u2192 Http): Order (context Models) is exposed in Http\u0027s public surface via OrderResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Shop/OrderResource.php"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"1601868256cc21a5242ef94a0b15c6e553b24082f0bfc9a2cf12415533bc0439"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PixelSize (Models \u2192 Http): PixelSize (context Models) is exposed in Http\u0027s public surface via PixelSizeResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Shop/PixelSizeResource.php"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"1080b91c61231d7f498bb6398d34478fc38409dd3429efdc931b879f6fd3f022"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PurchasablePrice (Models \u2192 Http): PurchasablePrice (context Models) is exposed in Http\u0027s public surface via PriceResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Shop/PriceResource.php"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2631e4e89fcfc0f324b07b50284a1a4ab7c50f9004746d6808247f977cf167f"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PrintSize (Models \u2192 Http): PrintSize (context Models) is exposed in Http\u0027s public surface via PrintSizeResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Shop/PrintSizeResource.php"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"41d43d8aab126ab01b0548777f9f00411e8a4e4f8ef34cb81cc6cfd48ced414e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PurchasablePixelSize (Models \u2192 Http): PurchasablePixelSize (context Models) is exposed in Http\u0027s public surface via PurchasablePixelSizeResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Shop/PurchasablePixelSizeResource.php"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"1afe2385c679a65d009841aa3d05ca5ab45466122dea0115ba0c91a9de2dc0c8"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PurchasablePrintSize (Models \u2192 Http): PurchasablePrintSize (context Models) is exposed in Http\u0027s public surface via PurchasablePrintSizeResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Shop/PurchasablePrintSizeResource.php"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bd9f8e749dc2497fb630ec911fff0e3b67d4db0a9afb4eb59707dfa4eb233ce"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Purchasable (Models \u2192 Http): Purchasable (context Models) is exposed in Http\u0027s public surface via PurchasableResource.fromModel \u2014 couples the contexts."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Shop/PurchasableResource.php"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e779343bc4598d86521d4f55bca3d95d90e5b2771eab5552b6b7bc4f4dc080f"}},{"ruleId":"D26","level":"note","message":{"text":"Projects may be oversized for their cohesion: 1 of 1 project(s) overshoot their size bounds, lowering Project Cohesion to 0.0/10. The most over is \u0060(repository root)\u0060 (175782 LoC, 1933 module-visible types across 255 directories). Review these for cohesion \u2014 draw the boundary inside the module first (group each responsibility into its own package or directory and keep the cross-boundary members non-public), since splitting a published package moves types between packages and breaks consumers."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d5a94650dc74886a0f1f08eb9fb6775f1fc395279ef7e901c970c9d26f767a72"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"9d46e33ea7bb4cb2648fab4c1edacc85a210f8a6a631381e8fc301aaf96b59a2"},"properties":{"commitSha":"078cd55a1743b60716fbeea7385a6adfc8599b53"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"98156559636061c96674921372bc9ff59a6be735e1fa41e53cda3ec013bdfbac"},"properties":{"commitSha":"6078acbfcdc2cfa4e4d2b52062b1fea2094df4f8"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"fdeeaee6463b89ffbbbbe3759f966fe09030ed5b3b12d63a97c8904a3da8586e"},"properties":{"commitSha":"6078acbfcdc2cfa4e4d2b52062b1fea2094df4f8"}},{"ruleId":"D28","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3cdfd7beb31b791ae18dcb425e21eb157c842e7bbcd522cc330573c1a6538db1"}},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d5b8f11381d61a58459ffc7c595fd52d09c03c711894a63a9578043d2338412b"},"taxa":[{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d7b3122417c778d211b4b5012ec64a66a177e37862cf9c087c9856ff1f2a965e"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"359e3c54fd7e5a67b3209cd58ad66e96edee082d42c7cb95347cff076802d6b1"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e473232be99e8185e9bc3dfee5966b709d530724f240ce4c1097f1d9f189aa6f"},"taxa":[{"id":"CWE-200","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A01:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"71ee4882f5bb778e768d2f81f3c6fbe44afb92fdaa4ff46a76ca00bb8fe7e450"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d95f1bc20a2bc7ca4505246e675d7bf0e313f30d895d2f936307bd9e7e6ca727"},"taxa":[{"id":"CWE-319","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A04:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D30","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d2e1b585684dc5e9da44db86fd0f94e3ac8a5e9e6dc2d540ed1d158023311ad5"}},{"ruleId":"D30","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"2f841b5dafe95e061b05f92cea23094f6f768c8e08dc988baa422ac26f1f4d7e"}},{"ruleId":"D30","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c3499ad0a977d322519aaca7110e923a983a15f44fe4e7df33bd5332385bfca5"}},{"ruleId":"D30","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"62adb9f5e9b97eba506c04d1d0815ef2266222d7effdc8e66c8016323c759fb0"}},{"ruleId":"D30","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6169b0e5c646778d853e7677e20f8c0f46c8daf29e69773a46f0451e9329e212"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"fe2d688610b51e0a5a02c7c5dd1724a4986e40f2689fb84510e2ec0164c27d6a"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"2e5e5f8154e585781fb0a3c06bad5c42235ca896a087d434aa5c249787c14943"},"taxa":[{"id":"CWE-250","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8ce67d8df97907e822a556dbfdce2b8529b6473fe41b692776235cbfebcc4def"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6a50f0d386a97c4720c24af5d34627b79e153c95081420b9994a22b26f117fec"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c5f99b0dbf31b393fd35f2cf3c646bc9f10a7daf71a125dbea84ac1400eb0162"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"805439a81df25dd3f7401ce0b10998c7dda0c1921eafd92cac318ff0cd64f58e"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"640a234759231bcf86d98e6495160ff846f357553c122e5ac7cd29a264ffc6e7"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b3bb2722d4bdf57d9b8f5dcb7bdbaa1d1568c08f03bb9b19bdb4c09fa514136b"},"taxa":[{"id":"CWE-276","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-732","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A01:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"156a3b3074ee457bbd25713a7038569817d4691672981f27a88cab8b9d0a1aee"},"taxa":[{"id":"CWE-276","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-732","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A01:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5e8fbae9f24103a78eb5432c4df49e470002816420b5b7c9e8910e48069235dc"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3e29604d7f016bac0a2b53ad56d9cb348d423a7ada7e9efd2d7ff6f4220b43f8"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/2021_12_04_181200_refactor_models.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2246f868816481e9036125674dbdc72f8f49b6949e53b641b3d8d5216603d272"}},{"ruleId":"D34","level":"note","message":{"text":"Further orphaned files (smaller): 38 smaller file(s) also have no living knowledge \u2014 folded into the freshness score and metrics rather than raised one row each \u2014 most significant first: app/Models/Extensions/ForwardsToParentImplementation.php, app/Services/Auth/SessionOrTokenGuard.php, app/Models/Extensions/UTCBasedTimes.php, app/Image/Files/NativeLocalFile.php, app/Actions/Photo/Rotate.php, resources/js/embed/utils/columns.ts, app/Image/PlaceholderEncoder.php, app/Image/Handlers/GoogleMotionPictureHandler.php (and 30 more) (39 orphaned of 620 analysed files in total, counted over production source files of roughly 2,400 bytes or more, excluding vendored, generated and example/demo trees and test files identified by path convention, largest first; 620 of the 2571 production source files in this repository met that bar). Attach the read to the next change that touches one of them: have a second person review that change, and leave behind a short comment or test recording what the file is for, so the knowledge comes back at the cost of a change you were making anyway."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"ce861fd78f6935114d3a342cb90ad25870f984e1042954fcbbe27c0e23be3658"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Extensions/ForwardsToParentImplementation.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8877662e456efb163a8c607f690ab6adfc5c58685bae89f578b36d84a0059e1"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Auth/SessionOrTokenGuard.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2cfd7df41749e4eff98e4991895b9a2754b8fa74ee6c4ba1106e56bc0869b01"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Extensions/UTCBasedTimes.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef194ebc7745a43f011192dafa59382b9b9bc08e0486785b633d7d7f84a3aac2"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/2021_05_25_160600_post_revert_fixes.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"892ecc97bc67ff62fa58cd0dcd917ec7788a1faea92288d7d598afd256f90243"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Image/Files/NativeLocalFile.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"738ce3f16e6ca9ad8c5be37b2d7e9947d7ca87992d23e4fdafeab3e7f17fe4c5"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/2022_10_23_143201_make_wui_settings_public.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"15d307678d57e40493fd7a59fb048a105461312255eb45d3b506ac44c03bbe4c"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/config.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3f2faf89e8a38340834622f00b51beb6c9df6367cc5479a03206ac6765d6c11"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/Rotate.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"446d9e7731f9586ca61a93cc253f719f5d872d66e44de5ac57c7253c5fc548a8"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/api.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f345a0c1b22d639afe2d65a6c16d2f469b68e0e81854fa0047781247f9129175"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/utils/columns.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a820d9c19e682ea2a2048c266dbdb90575cfab272befa90bfa80fcc5eed3e93"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/2021_05_13_140700_refactor_size_variants.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"34df411b56fc2363e134e03196e3a5397525d781d89da3650a209206a97b46e9"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Image/PlaceholderEncoder.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f91b387916fc3c7ae0e4fe3118fd0c506cad3eb65897afb6e90c0eb7a9468e75"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/2026_02_28_000006_add_contact_form_configs.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1f408e1aa24057c122db11193e89933a6d7f4f346ffaffbec9ab42151551bbe"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Image/Handlers/GoogleMotionPictureHandler.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"67b594186bbeb4b79d37ca78000f69d04b48cb08f87a233613091e1a612aa8bb"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Image/Files/FlysystemFile.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c73cf9a68c263d49ea1c5c711991ec893cb27b6e099d253c32278256a4d3990b"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Image/Files/BaseMediaFile.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"97f306a84991ff378324d604eb567285ba1ba5f00c57cc75d59d087e6df53670"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/layouts/filmstrip.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5252e09ee237c0b4c6ee8d794c1707ec9705b690f07d2d90d5aa69271f2ba63c"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/Laravel/Optimize.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fdb754360a33bc5b8601994ddd27c357576bccf36c7d596e05897edd68e1dce8"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/WebhookDispatchJob.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1c6050d2ec29de60a9682082f7f7ae6782d75995c12b946272239cebfd20636"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Contact/ContactController.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"82198f4451b88a21394c64be35b9059a65d6d251a46d2261d63ae2eaf089f590"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/SecurityAdvisoriesService.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"48f87c07ab41328f701c85e36fb2bc53d2713b7c488c25a4801b2ec4205290de"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Contracts/Models/SizeVariantFactory.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"69f07369b5a31cde25834db1fa20d61232a6c915e5549250d7f7fdf8315f463c"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/DTO/BacktraceRecord.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6901827c1456fe1f41663764bcbb39fdc6dd6edd8c1d7c2534617c6ba164dc9c"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Contracts/Image/ImageHandlerInterface.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8429c03fa14970caebe1dd57053d6da0275f5410b44a1686f5878833a96ba7e"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Webhook.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"127d0868c670f1f1d468735d078f0acc35e532ecdcc6dfd400a0624ea5bddb49"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Listeners/WebhookListener.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"19964f05f6242c316bb746425480a71bec158ab19a4c610b86ab95febe0807f0"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/2021_05_02_174300_add_filesize_raw_col.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f765769c82d281fb8d29ad934885d58a43a985456ce2fc1122c11132971d491"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Contracts/Models/HasUTCBasedTimes.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0a22f8ae656d51615b1342af7a1324cfde8f39d5763318c8f010b1b62a1b02c"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Image/Files/AbstractBinaryBlob.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"424ff0d15740e03421995defac854ce4a294f1d3f89c4580ae5ea434cc306d25"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Requests/Album/UpdateAlbumHeaderRequest.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d7cc9d34ac76295f7b52ca7d34c3c245ed48c1e6d438089e3d0b6fcfbdc0a34"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/main.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"365a955a5215820a5b07d5613e78b2f15e735871151f80df2ee689dfec6e7bdd"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Image/Files/InMemoryBuffer.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c02ca75c487bff5ae1fe218b9b5581cc55eed66ecfffd0716785c9a2dd731d69"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/factories/WebhookFactory.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8e21e1ee3fb166312d613ef3d1ac2c77dae98f5c4d60167491cc83a0724b612"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Exceptions/BaseLycheeException.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fcc9c59543b42ff825e0140015c335532fe368d7a7c75255c9644139e9b0244"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/DTO/Version.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c17f2b4f07c57ae8af049dae0ea6f67e246a1227568bbf7a0f48cbbc34625c86"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Webhook/WebhookPayloadBuilder.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"66ad03f815858ef2906cceb345843acf6b7f467aa43b3090d350dbf298b7d1c2"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Diagnostics/Pipes/Checks/PlaceholderExistsCheck.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"66699c6445ab7ea00b4f327e7a25f7e46d2b44c3bb067ecd05bc9cbe461f2027"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/DTO/WebhookPayload.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a47ecb067d30978f6d5b2d256193a126f5b3bfea5a17855c4aa87f911343626"}},{"ruleId":"D35","level":"warning","message":{"text":"Change-coupling hub: all_settings.php \u2192 all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php: \u0060lang/nl/all_settings.php\u0060 changes together with 19 other files \u2014 \u0060lang/ar/all_settings.php\u0060, \u0060lang/bg/all_settings.php\u0060, \u0060lang/cz/all_settings.php\u0060, \u0060lang/de/all_settings.php\u0060, \u0060lang/el/all_settings.php\u0060, \u0060lang/es/all_settings.php\u0060, \u0060lang/fa/all_settings.php\u0060, \u0060lang/hu/all_settings.php\u0060, \u0060lang/it/all_settings.php\u0060, \u0060lang/ja/all_settings.php\u0060, \u0060lang/no/all_settings.php\u0060, \u0060lang/pl/all_settings.php\u0060, \u0060lang/ru/all_settings.php\u0060, \u0060lang/sk/all_settings.php\u0060, \u0060lang/sv/all_settings.php\u0060, \u0060lang/tr/all_settings.php\u0060, \u0060lang/vi/all_settings.php\u0060, \u0060lang/zh_CN/all_settings.php\u0060, \u0060lang/zh_TW/all_settings.php\u0060 \u2014 none of which declares a dependency on it: one file is the hub of 19 separate couplings, not 19 unrelated pairs. Read the hub first: if the others each duplicate a part of what it does, the shared concern belongs in ONE unit and extracting it clears every edge at once; if the hub is a registry, dispatcher or barrel that must name each of them, the coupling is structural and the question is whether that list can be discovered instead of enumerated. Fixing the hub is one change; breaking the couplings one pair at a time is 19."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/nl/all_settings.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bb20e2bd4d6b4d479e4c8383d10c415c6b0108972705946ad4f7d5db5647881"}},{"ruleId":"D35","level":"warning","message":{"text":"Change-coupling hub: all_settings.php \u2192 all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php, all_settings.php: \u0060lang/en/all_settings.php\u0060 changes together with 9 other files \u2014 \u0060lang/ar/all_settings.php\u0060, \u0060lang/bg/all_settings.php\u0060, \u0060lang/es/all_settings.php\u0060, \u0060lang/fa/all_settings.php\u0060, \u0060lang/ja/all_settings.php\u0060, \u0060lang/no/all_settings.php\u0060, \u0060lang/ru/all_settings.php\u0060, \u0060lang/sv/all_settings.php\u0060, \u0060lang/tr/all_settings.php\u0060 \u2014 none of which declares a dependency on it: one file is the hub of 9 separate couplings, not 9 unrelated pairs. Read the hub first: if the others each duplicate a part of what it does, the shared concern belongs in ONE unit and extracting it clears every edge at once; if the hub is a registry, dispatcher or barrel that must name each of them, the coupling is structural and the question is whether that list can be discovered instead of enumerated. Fixing the hub is one change; breaking the couplings one pair at a time is 9."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/en/all_settings.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"05ad4cd6461f3dab7d7ff2cb497ebfb1cffadd17c6918a70131b281e19f43b4b"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: all_settings.php \u2194 all_settings.php: \u0060lang/ja/all_settings.php\u0060 and \u0060lang/pt/all_settings.php\u0060 change together 100% of the time (14 of the 14 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets) with no explicit dependency \u2014 the edge is real but nothing declares it. Read the pair before acting: if one registers itself into the other through a hook or an initialiser, the missing dependency is DELIBERATE \u2014 the registration is the link, and it is meant not to be an import \u2014 and the thing to add is a comment on each side naming the other, not a merge; if they simply belong together, co-locate them; if neither holds, the coupling is hidden and worth breaking. You can check this without leaving the row: of the 14 shared commits counted here, the most recent 3 are \u00609071f8bd\u0060 Ensure that config always have translation keys (#4872); \u0060cea5c725\u0060 Fix: Don\u0027t show sensitive photos in landing (#4821); \u006001d64381\u0060 Add support for video loop attribute (#4807) \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/ja/all_settings.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ad98412ae4b183a87db76accdbdc81513f0680c2043be6d53b5938f3269bf61"}},{"ruleId":"D35","level":"warning","message":{"text":"Change-coupling hub: dialogs.php \u2192 dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php: \u0060lang/ja/dialogs.php\u0060 changes together with 16 other files \u2014 \u0060lang/cz/dialogs.php\u0060, \u0060lang/de/dialogs.php\u0060, \u0060lang/en/dialogs.php\u0060, \u0060lang/fr/dialogs.php\u0060, \u0060lang/hu/dialogs.php\u0060, \u0060lang/it/dialogs.php\u0060, \u0060lang/nl/dialogs.php\u0060, \u0060lang/no/dialogs.php\u0060, \u0060lang/pl/dialogs.php\u0060, \u0060lang/pt/dialogs.php\u0060, \u0060lang/ru/dialogs.php\u0060, \u0060lang/sk/dialogs.php\u0060, \u0060lang/sv/dialogs.php\u0060, \u0060lang/vi/dialogs.php\u0060, \u0060lang/zh_CN/dialogs.php\u0060, \u0060lang/zh_TW/dialogs.php\u0060 \u2014 none of which declares a dependency on it: one file is the hub of 16 separate couplings, not 16 unrelated pairs. Read the hub first: if the others each duplicate a part of what it does, the shared concern belongs in ONE unit and extracting it clears every edge at once; if the hub is a registry, dispatcher or barrel that must name each of them, the coupling is structural and the question is whether that list can be discovered instead of enumerated. Fixing the hub is one change; breaking the couplings one pair at a time is 16."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/ja/dialogs.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"be7ccc8b7a22e273f467c530091d27b8610179a0f3ccf055e59ef9a9b7005c68"}},{"ruleId":"D35","level":"warning","message":{"text":"Change-coupling hub: dialogs.php \u2192 dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php: \u0060lang/pt/dialogs.php\u0060 changes together with 15 other files \u2014 \u0060lang/cz/dialogs.php\u0060, \u0060lang/de/dialogs.php\u0060, \u0060lang/en/dialogs.php\u0060, \u0060lang/fr/dialogs.php\u0060, \u0060lang/hu/dialogs.php\u0060, \u0060lang/it/dialogs.php\u0060, \u0060lang/nl/dialogs.php\u0060, \u0060lang/no/dialogs.php\u0060, \u0060lang/pl/dialogs.php\u0060, \u0060lang/ru/dialogs.php\u0060, \u0060lang/sk/dialogs.php\u0060, \u0060lang/sv/dialogs.php\u0060, \u0060lang/vi/dialogs.php\u0060, \u0060lang/zh_CN/dialogs.php\u0060, \u0060lang/zh_TW/dialogs.php\u0060 \u2014 none of which declares a dependency on it: one file is the hub of 15 separate couplings, not 15 unrelated pairs. Read the hub first: if the others each duplicate a part of what it does, the shared concern belongs in ONE unit and extracting it clears every edge at once; if the hub is a registry, dispatcher or barrel that must name each of them, the coupling is structural and the question is whether that list can be discovered instead of enumerated. Fixing the hub is one change; breaking the couplings one pair at a time is 15."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/pt/dialogs.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4bcf32ea9289c06616e6059ee88bf86dccbe9440b9f6ab0d798e5bb0e13fe474"}},{"ruleId":"D35","level":"warning","message":{"text":"Change-coupling hub: dialogs.php \u2192 dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php: \u0060lang/el/dialogs.php\u0060 changes together with 19 other files \u2014 \u0060lang/cz/dialogs.php\u0060, \u0060lang/de/dialogs.php\u0060, \u0060lang/en/dialogs.php\u0060, \u0060lang/es/dialogs.php\u0060, \u0060lang/fa/dialogs.php\u0060, \u0060lang/fr/dialogs.php\u0060, \u0060lang/hu/dialogs.php\u0060, \u0060lang/it/dialogs.php\u0060, \u0060lang/ja/dialogs.php\u0060, \u0060lang/nl/dialogs.php\u0060, \u0060lang/no/dialogs.php\u0060, \u0060lang/pl/dialogs.php\u0060, \u0060lang/pt/dialogs.php\u0060, \u0060lang/ru/dialogs.php\u0060, \u0060lang/sk/dialogs.php\u0060, \u0060lang/sv/dialogs.php\u0060, \u0060lang/vi/dialogs.php\u0060, \u0060lang/zh_CN/dialogs.php\u0060, \u0060lang/zh_TW/dialogs.php\u0060 \u2014 none of which declares a dependency on it: one file is the hub of 19 separate couplings, not 19 unrelated pairs. Read the hub first: if the others each duplicate a part of what it does, the shared concern belongs in ONE unit and extracting it clears every edge at once; if the hub is a registry, dispatcher or barrel that must name each of them, the coupling is structural and the question is whether that list can be discovered instead of enumerated. Fixing the hub is one change; breaking the couplings one pair at a time is 19."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/el/dialogs.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"69ee9abe326447f90ac1575fc8e5ed1301ed1f0de0b10cf67e71ad1961668875"}},{"ruleId":"D35","level":"warning","message":{"text":"Change-coupling hub: dialogs.php \u2192 dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php: \u0060lang/zh_TW/dialogs.php\u0060 changes together with 12 other files \u2014 \u0060lang/cz/dialogs.php\u0060, \u0060lang/de/dialogs.php\u0060, \u0060lang/en/dialogs.php\u0060, \u0060lang/fr/dialogs.php\u0060, \u0060lang/hu/dialogs.php\u0060, \u0060lang/it/dialogs.php\u0060, \u0060lang/nl/dialogs.php\u0060, \u0060lang/no/dialogs.php\u0060, \u0060lang/pl/dialogs.php\u0060, \u0060lang/sk/dialogs.php\u0060, \u0060lang/sv/dialogs.php\u0060, \u0060lang/vi/dialogs.php\u0060 \u2014 none of which declares a dependency on it: one file is the hub of 12 separate couplings, not 12 unrelated pairs. Read the hub first: if the others each duplicate a part of what it does, the shared concern belongs in ONE unit and extracting it clears every edge at once; if the hub is a registry, dispatcher or barrel that must name each of them, the coupling is structural and the question is whether that list can be discovered instead of enumerated. Fixing the hub is one change; breaking the couplings one pair at a time is 12."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/zh_TW/dialogs.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d194f80c90a1f7da5ac8ae0b946f64b8d3118c3c2e9e7f0f99cccd727c9e419"}},{"ruleId":"D35","level":"warning","message":{"text":"Change-coupling hub: dialogs.php \u2192 dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php: \u0060lang/zh_CN/dialogs.php\u0060 changes together with 13 other files \u2014 \u0060lang/cz/dialogs.php\u0060, \u0060lang/de/dialogs.php\u0060, \u0060lang/en/dialogs.php\u0060, \u0060lang/fr/dialogs.php\u0060, \u0060lang/hu/dialogs.php\u0060, \u0060lang/it/dialogs.php\u0060, \u0060lang/nl/dialogs.php\u0060, \u0060lang/no/dialogs.php\u0060, \u0060lang/pl/dialogs.php\u0060, \u0060lang/sk/dialogs.php\u0060, \u0060lang/sv/dialogs.php\u0060, \u0060lang/vi/dialogs.php\u0060, \u0060lang/zh_TW/dialogs.php\u0060 \u2014 none of which declares a dependency on it: one file is the hub of 13 separate couplings, not 13 unrelated pairs. Read the hub first: if the others each duplicate a part of what it does, the shared concern belongs in ONE unit and extracting it clears every edge at once; if the hub is a registry, dispatcher or barrel that must name each of them, the coupling is structural and the question is whether that list can be discovered instead of enumerated. Fixing the hub is one change; breaking the couplings one pair at a time is 13."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/zh_CN/dialogs.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"398a097eaca3f97055e0daf8a0cf299d3d7f84f47ed97c41e7fc0171412a32a9"}},{"ruleId":"D35","level":"warning","message":{"text":"Change-coupling hub: dialogs.php \u2192 dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php: \u0060lang/ru/dialogs.php\u0060 changes together with 14 other files \u2014 \u0060lang/cz/dialogs.php\u0060, \u0060lang/de/dialogs.php\u0060, \u0060lang/en/dialogs.php\u0060, \u0060lang/fr/dialogs.php\u0060, \u0060lang/hu/dialogs.php\u0060, \u0060lang/it/dialogs.php\u0060, \u0060lang/nl/dialogs.php\u0060, \u0060lang/no/dialogs.php\u0060, \u0060lang/pl/dialogs.php\u0060, \u0060lang/sk/dialogs.php\u0060, \u0060lang/sv/dialogs.php\u0060, \u0060lang/vi/dialogs.php\u0060, \u0060lang/zh_CN/dialogs.php\u0060, \u0060lang/zh_TW/dialogs.php\u0060 \u2014 none of which declares a dependency on it: one file is the hub of 14 separate couplings, not 14 unrelated pairs. Read the hub first: if the others each duplicate a part of what it does, the shared concern belongs in ONE unit and extracting it clears every edge at once; if the hub is a registry, dispatcher or barrel that must name each of them, the coupling is structural and the question is whether that list can be discovered instead of enumerated. Fixing the hub is one change; breaking the couplings one pair at a time is 14."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/ru/dialogs.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"768da4b4a9601cd70c4363c11e2e2295cacc483312deaed13196e38b382c9cc1"}},{"ruleId":"D35","level":"warning","message":{"text":"Change-coupling hub: dialogs.php \u2192 dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php: \u0060lang/es/dialogs.php\u0060 changes together with 18 other files \u2014 \u0060lang/cz/dialogs.php\u0060, \u0060lang/de/dialogs.php\u0060, \u0060lang/en/dialogs.php\u0060, \u0060lang/fa/dialogs.php\u0060, \u0060lang/fr/dialogs.php\u0060, \u0060lang/hu/dialogs.php\u0060, \u0060lang/it/dialogs.php\u0060, \u0060lang/ja/dialogs.php\u0060, \u0060lang/nl/dialogs.php\u0060, \u0060lang/no/dialogs.php\u0060, \u0060lang/pl/dialogs.php\u0060, \u0060lang/pt/dialogs.php\u0060, \u0060lang/ru/dialogs.php\u0060, \u0060lang/sk/dialogs.php\u0060, \u0060lang/sv/dialogs.php\u0060, \u0060lang/vi/dialogs.php\u0060, \u0060lang/zh_CN/dialogs.php\u0060, \u0060lang/zh_TW/dialogs.php\u0060 \u2014 none of which declares a dependency on it: one file is the hub of 18 separate couplings, not 18 unrelated pairs. Read the hub first: if the others each duplicate a part of what it does, the shared concern belongs in ONE unit and extracting it clears every edge at once; if the hub is a registry, dispatcher or barrel that must name each of them, the coupling is structural and the question is whether that list can be discovered instead of enumerated. Fixing the hub is one change; breaking the couplings one pair at a time is 18."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/es/dialogs.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e495f4a998b275fd3b81d1527ca57e54cbf2cf6cdc3a96edae4d8f1418b8b62"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: all_settings.php \u2194 all_settings.php: \u0060lang/fr/all_settings.php\u0060 and \u0060lang/ja/all_settings.php\u0060 change together 93% of the time (13 of the 14 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets) with no explicit dependency \u2014 the edge is real but nothing declares it. Read the pair before acting: if one registers itself into the other through a hook or an initialiser, the missing dependency is DELIBERATE \u2014 the registration is the link, and it is meant not to be an import \u2014 and the thing to add is a comment on each side naming the other, not a merge; if they simply belong together, co-locate them; if neither holds, the coupling is hidden and worth breaking. You can check this without leaving the row: of the 13 shared commits counted here, the most recent 3 are \u00609071f8bd\u0060 Ensure that config always have translation keys (#4872); \u0060cea5c725\u0060 Fix: Don\u0027t show sensitive photos in landing (#4821); \u006001d64381\u0060 Add support for video loop attribute (#4807) \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/fr/all_settings.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"03738ea6078b6f6903887b9dbdcee11213d396085909d025a06395afa77738cb"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling clique: maintenance.php, maintenance.php, maintenance.php, maintenance.php, maintenance.php, maintenance.php: 6 files \u2014 \u0060lang/de/maintenance.php\u0060, \u0060lang/en/maintenance.php\u0060, \u0060lang/es/maintenance.php\u0060, \u0060lang/fr/maintenance.php\u0060, \u0060lang/no/maintenance.php\u0060, \u0060lang/zh_TW/maintenance.php\u0060 \u2014 all change together with no explicit dependency: a fully-connected co-change clique, not 15 separate couplings. They share one concern (thin parallel siblings over a common abstraction), so extract the shared part into ONE unit and the whole clique\u0027s coupling clears at once \u2014 you do not need to break each pair individually."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/de/maintenance.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b866449824aa7752aacec3bad23db12efc20078cae7391e96d9fa61af0a695a5"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: InitConfig.php \u2194 LycheeState.ts: \u0060app/Http/Resources/GalleryConfigs/InitConfig.php\u0060 and \u0060resources/js/stores/LycheeState.ts\u0060 change together 88% of the time (22 of the 25 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets) and are written in DIFFERENT LANGUAGES, so no import can join them and they cannot be co-located into one unit \u2014 they compile and ship as separate artifacts. What binds them is a CONTRACT across that boundary \u2014 an event or message name, a route, a serialised shape \u2014 that each side currently spells out on its own, which is exactly why a change to one drags the other. Declare that contract once where both sides read it (a shared schema, a generated constants file, an interface-definition file) so a change on one side fails the other\u0027s build instead of drifting silently; where the surface is too small to be worth that, name the counterpart in a comment on both sides so the next reader finds it. There is nothing here to merge. You can check this without leaving the row: of the 22 shared commits counted here, the most recent 3 are \u006001d64381\u0060 Add support for video loop attribute (#4807); \u00609fe1d715\u0060 Add setting to show highest-quality image in the full-screen viewer (\u2026; \u0060c8769e6f\u0060 Add more configuration settings... (#4643) \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/GalleryConfigs/InitConfig.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1268248a6405750cfb0164a8362ea1993fc56b7d18454650a06d2428b23ecbc0"}},{"ruleId":"D35","level":"warning","message":{"text":"Change-coupling hub: dialogs.php \u2192 dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php, dialogs.php: \u0060lang/fa/dialogs.php\u0060 changes together with 17 other files \u2014 \u0060lang/cz/dialogs.php\u0060, \u0060lang/de/dialogs.php\u0060, \u0060lang/en/dialogs.php\u0060, \u0060lang/fr/dialogs.php\u0060, \u0060lang/hu/dialogs.php\u0060, \u0060lang/it/dialogs.php\u0060, \u0060lang/ja/dialogs.php\u0060, \u0060lang/nl/dialogs.php\u0060, \u0060lang/no/dialogs.php\u0060, \u0060lang/pl/dialogs.php\u0060, \u0060lang/pt/dialogs.php\u0060, \u0060lang/ru/dialogs.php\u0060, \u0060lang/sk/dialogs.php\u0060, \u0060lang/sv/dialogs.php\u0060, \u0060lang/vi/dialogs.php\u0060, \u0060lang/zh_CN/dialogs.php\u0060, \u0060lang/zh_TW/dialogs.php\u0060 \u2014 none of which declares a dependency on it: one file is the hub of 17 separate couplings, not 17 unrelated pairs. Read the hub first: if the others each duplicate a part of what it does, the shared concern belongs in ONE unit and extracting it clears every edge at once; if the hub is a registry, dispatcher or barrel that must name each of them, the coupling is structural and the question is whether that list can be discovered instead of enumerated. Fixing the hub is one change; breaking the couplings one pair at a time is 17."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"lang/fa/dialogs.php"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a8814bc36c2774d7ea9bf3fa5091d36e8bfe1f94528832f5136f3859881b32d"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"eb00976a698a5d68999b7ee6d27206fd374e916853e7ff1ead5eed42386f043f"},"taxa":[{"id":"CICD-SEC-9","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"fcd57380e15eb705310e9baaca557585b376a0ce4ff0a486d0acfc5c3cbd5312"},"taxa":[{"id":"CICD-SEC-5","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"4f1e7684f8281bd255ddef97105c7055c2ebae06964c8745716b83e174debe83"}},{"ruleId":"AC1","level":"warning","message":{"text":"\u003Cvideo\u003E without a captions track: Video with no captions \u003Ctrack\u003E offers no captions. This player\u0027s source is set at runtime, so there is no caption file to author here: give the player a way to carry captions \u2014 accept a track/captions URL alongside the media and render a \u003Ctrack kind=\u0022captions\u0022\u003E when one is supplied \u2014 and capture that asset wherever the media enters the product (upload, import or generation)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/components/Lightbox.vue"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"a94b4fb89f106c784ea080a44926265314f0b0f7923c0aaa6d07f4de25cb4f23"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/LiveMetrics.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"5eea9449d5da577598e696ea4a188a81c0971e1fbad14e5571e0d5afec99c4ce"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/card/Card.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c1618fa800488d00cfbf91a88c1d51a72524bc6d058fafee444962fcf4ed36d"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/card/Card.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"4895f8bc3b6730da76898e016ba1afab76974063c2b1507df8b0831e394280e6"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/card/Card.vue"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"c88b3ed76984379fd95cc2cfe3919e351187806e55b7cff595832833f5a57094"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumHeaderImage.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff55836c21cc5852548b78917e4136149457de3ce5bebf071073afc929ec56bd"}},{"ruleId":"AC1","level":"warning","message":{"text":"\u003Cvideo\u003E without a captions track: Video with no captions \u003Ctrack\u003E offers no captions. This player\u0027s source is set at runtime, so there is no caption file to author here: give the player a way to carry captions \u2014 accept a track/captions URL alongside the media and render a \u003Ctrack kind=\u0022captions\u0022\u003E when one is supplied \u2014 and capture that asset wherever the media enters the product (upload, import or generation)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoBox.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa5b9e0628516fca8dedab566e7842940fbedefaf71c7a94a877ca9eecc23713"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/AlbumsHeader.vue"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"99d9cab1ba779c41bc5adf01baa4617e08f58967d4ebdaee904cab13b2ecfae6"}},{"ruleId":"AC1","level":"warning","message":{"text":"\u003Ccanvas\u003E without a text alternative: A \u003Ccanvas\u003E with no aria-label/title and no inner fallback content can\u0027t be described by assistive tech. Add a name or fallback content."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/QrCodeLink.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"99b3b06852c8436bf2f43de649aa3702671041263d8384957389295f13858aba"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/DuplicatesFinder.vue"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"9de4cd9fe41e15f122d2518eae56377daebb6c4ad21b95aa1ff2a5797820f0c0"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"44263bfec391305690a8a77ca4998cbc641c64d9340f96c9c21455b05fa3f5ab"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoDetails.vue"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad1cf7dcc59bafa558c539ce6cb8105dd18fe68f8b3f9059c2dd7c3e00c192f6"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoDetails.vue"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"fabecabe794d692eb26eda86eac9018a360a0573550af99f9a51b601547f0575"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoDetails.vue"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f2115d93b40501b6388c88c2a240656253a1422c3d06b3f2eea9f8c4cabc5b3"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoDetails.vue"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"09b86e6aacf6c36d03439f987680831aa6219713712988f1668bdb9d17f1c1aa"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/card/Card.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"16935656599d9c54f320d311d092706cc583e59d8ceda47e0c4865ad28a2c899"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/card/Card.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"86d9ed712fe20c6f8874291db5f1b5a7c18c97793a621735419e885ceb86d955"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/card/Card.vue"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2944471b0f868d9995c960f42121be87b85aeabdad71c0c77a32d2f738cbc21"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHeaderImage.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"985a70037f96009a3650591740f90bb9826f403985cfb172c0d48f3132296d5b"}},{"ruleId":"AC1","level":"warning","message":{"text":"\u003Cvideo\u003E without a captions track: Video with no captions \u003Ctrack\u003E offers no captions. This player\u0027s source is set at runtime, so there is no caption file to author here: give the player a way to carry captions \u2014 accept a track/captions URL alongside the media and render a \u003Ctrack kind=\u0022captions\u0022\u003E when one is supplied \u2014 and capture that asset wherever the media enters the product (upload, import or generation)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoBox.vue"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1aee01d3f4f7eb34ee7a9cb448efa4f75dcc1d528096c2946d9ba6b346c0ef7"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/AlbumsHeader.vue"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"b769aaec295a4e16155c8b4f041d9b8fc88a0e2c580b2b3f710cb069abf66100"}},{"ruleId":"AC1","level":"warning","message":{"text":"\u003Ccanvas\u003E without a text alternative: A \u003Ccanvas\u003E with no aria-label/title and no inner fallback content can\u0027t be described by assistive tech. Add a name or fallback content."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/QrCodeLink.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"726defe87659ceeca38ff46522b6d5f32107b1ec7742a2bbd523783cce84888a"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/DuplicatesFinder.vue"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce5cd594d43d2d01d6abb85076e1ac0978392024b9b737d4e1dd0c9f46f8c1fe"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/LiveMetrics.vue"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fae5e8dfa7cf6eed0551111f20848d914b0ae11fc4f3e64547cd9ecdcb1a2da"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/LiveMetrics.vue"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"479f634a2926b907376097c9a4f833a0585908a7158dbb95f0c34b41a57ef2e9"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/faceRecog/FaceRecognitionWarning.vue"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"376ac09422873b1e9772559fbfca43536fe1d6bebb7866f8db96867e93d14d31"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/GalleryFooter.vue"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"21d4f0996ee3460cb808017fd3a90f6ce97379ce227e47de1c9378c6885d425b"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/GalleryFooter.vue"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"477e8b8baebc28b2b75db61138491d97d0e6f5b1cd4fdcc6e864f6ad11156cf3"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/GalleryFooter.vue"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4ff5f5635f65ee6ecc6f4ad12bb2429dd11d25bce28bf0d1c3290470d0a4a39"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/GalleryFooter.vue"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"55ff0e0acfaf85af1f31c70b79372504eb70c324b53545f698df30130f879db4"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/GalleryFooter.vue"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c9e19a732fec20e0bcb5efb7e3607980e4a21fc7b21ed830645a2aa051b382f"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/LandingFooter.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"3688ecfaa86a77fb1d23f20241e44a3f62c709ef652658941de4e5d1c6e0cc82"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/LandingFooter.vue"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c9ad0498d44b3dd4828d43564614d4e30c6d684b778a1eafacafb15d27f7019"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/LandingFooter.vue"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"e56fa36c7f698e015597851587bb8127377e71286d1923a534c4793836a8ed25"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/LandingFooter.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"701e262569008609affd92438bc82c704fac93cff19f911e0df30d83e61f59e3"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/LandingFooter.vue"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"66eabeaa272dfb6c2e4e7c7691926dda80ba99ca641359d32abaf3d94ee4749d"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/SearchTargetAlbum.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc395b78b9eafae9d052f9a8bb4bc661a2e1887346c0ca52e23cb98c75ac6b81"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/SearchTargetUser.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5ba0ac14635b66b05d636af25cd5f877e52ec8266bd9f3a6c3897a27ead2f61"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/Fieldset.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"874e871f80458ac7628dd95d279d7d87e44f7df46903de9b9048c2ce26bc97fd"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/PersonInput.vue"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"7defb5e9ca468b7b91644e95a9f7cc07c931cdd5f4fe1b24b1954816895533ee"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/PersonInput.vue"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"343294c71d614339b4fedb6727147edbdec62ac53b990cdb178745f104311936"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/PersonInput.vue"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"15b4a8a2cf43cf11bd1eda0ee5f55a9fa31f977bf3619b5730c221ace768a1e6"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Ctextarea\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/Textarea.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"020059f5dfa6f520a3b1f209b1c137bb24fd02759587006cf992cfd001dd4cee"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/rating.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9068479679397fe787cfb628d2dd25b07904687f9a2ceeedb8f7ffa943b5f3c"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/card/CardForm.vue"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"5865f7bdbbe18801416b5a169773de6fa6b0b23b1cd43b415a1fb360e3d245e6"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetLogin.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"2536968b61a1d6cc4b66b68aab36fab468c716c8a94c1c0d24ab12953b95b45b"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetOauth.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c9c4675d4af96550cef8b9f4cbdfe09735fbd90fb65369f56faeb9a89fa89a2"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetSecondFactor.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"32a8d1dd5e9615b31c41ed75ba514c529e727902877843b3f98df2a1aceddd06"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetSharedAlbumsVisibility.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b565180b2950dc6bdf4af6ee050c6ef02827c61dbf81b49383cae44937c0582"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetSharedAlbumsVisibility.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"9416431699adab376a37baa57eebda1fa38aa382edf96b048658340f2e049d21"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"d76b2d7157c2451400251f42cf60935fc075a417813fbd6c98cbe125028b96da"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d5e0a180b5a099d5d1188255b1ec82ffa930f417009098b53160cc0ee8e3e33"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3a82185ddb7389e81b68fd7db7043f701f0f19a9265cf74fd1ba7b56d12465b"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"14d1a388a94d1bc95c48e99afab046bb215b8d7b7ff6c4ce1e06d8d89b09ff68"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1b36658b3eb381f1f2d275d8258bf2ecad577651f5c51f51eae275c503c7dcb"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fc057adae4203abc1f0883cbdb82bac343431010ad26b095987a20ff898328d"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"63827105b2df902e399c1533bb0748fb712f5618e0565c8b706fd06063c31c6a"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"401e6a388f92376369b6cd4948ca7c00847cff49be392c018b717b7e3dc3075d"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fe6dc8de12b317615365d7fc82000990ee148a041778b94d0dc3cd75027a7f8"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"33fd6b892bfa867344f00bd91a58fd59f965ebb9013b2687a7c1214146341041"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"057b4dc723764736940b1f4141b19d2ae04f3405c1fcd45468d233fa105ff247"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d9b4c6588f9101f7ab02149d01d9047957ce8f0bd717117076968554f9c255b"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"adfe3df1047c68a7c7d4b5104c2badb0f2a8702fab4ff9c73f70fcc9376bc56f"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bf2d1968e2602e4b64ccceb8ab49390cf8de700f1ae7980824a5e597945e946"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"83dda515d0533e824d3755d1ba514034d140c665fe304c46b88e412495943eff"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"e93ce4a8e70a9fdda28fd37425caff57327cc5003415537df827bc05a230ff8f"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"88f75b206dc88032365c7f8993fd55f09c0a200221d8808265ab048a29d1daa5"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"1edabc7020b10ac32c549639c29c4f6125c316851d066bc75ef54cbd55e0838e"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"fda92252e4aa691de10dd50357e5b404f619c8b4008e388760d2730ca521c495"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"25a02dcaca29fe1a886f718c8eb108987f8516ab7fa0eacd51bb599c08c7043e"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"77e1524408dc1825cd2669210abb310de50e4d0184c709bacf96d9d515090218"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"9dce28ba2336bede76808d9fca246a76d8eabeb6d5c7dbf1a1bce5a071fd50ef"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a92daa138bcd5c797c32d3e67924cafb051d7f66846376975ea0c887fc93b68"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"e377d8e80f951a3d12f5f37367da89e09280df8abca5887163601fb55b59bd25"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"a498d78287829d22ef6c937a3637331ec2db09718d96a7f60c1e0a49fed02f53"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/SearchInputBar.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"22bca8a5d0564b9e5c1007ef47da18035e62e03cae01cfde34bbec7ff98a3f4e"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/PasswordField.vue"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c41fe50904459fb4dbc1b357db6601b52e8fa1bbd07bb70b480d70d17b41e2a"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Cspan\u003E: This \u003Cspan\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/sharing/CreateSharing.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c4ccabdadca2bcca002eee48e64c534aaefce7579e997fbda1701f698fb33fc"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PixelSizePricesInput.vue"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"72ab2e054ecd2876b038359a5cc6b8f5ee511857b3ba19eb3ab773a305514712"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PixelSizePricesInput.vue"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"3db1cb862eed64f1a15e127f7f7405a8cbb9864a0a087d24dfdd911ad0306672"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PixelSizePricesInput.vue"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"6528fd1adc895ec807585486af752d71910364999e98f201421855b539849edb"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PricesInput.vue"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e99a7d5a70232f4918eef9b95b9df52c9e3d7e926139d2cf7bea7a2bc4c5b50"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PricesInput.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"757a3fce68e4a178717f1340576b7ed8529c11db81d45b80ce4311f72097421a"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PricesInput.vue"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"03bb49866eef7ebf18561f0bd77cf940cfbb19ab15542e4c8843b5c4d8f17a7f"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PrintSizePricesInput.vue"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"5abe9098dbf2fdad2fbb5ba46ce945f2d1bbbc1f5b2fd2280c23b1a8eb352005"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PrintSizePricesInput.vue"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0f9736ec8a4f2390495f77188f09a2341bb65dd9c74e54f6cb4d872ab88bc1a"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PrintSizePricesInput.vue"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b0bfdc5b3f515969da204c406373fe95cc8b45968d7094bc9b051074d5025e4"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/upload/DropBoxChooser.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"61d409a0658575a29ef9237bd8d0d2c9311151ad86470b3f40ff60cd300daac9"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumPeopleFilter.vue"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"b3dba8197e3b1492713c9cf7d7db394d0971a2006763c8875769b1e3a5ef8734"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumTagFilter.vue"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"e21467a03c77e096aa6606511ae608d20825b529e510f4a5c1b44740a8e4fe4d"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumTagFilter.vue"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a62c988a927c39e4371ddc40eacc77bb417c4a44111bf211900d14f02f4bc1c"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumTagFilter.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"05a03bc5a538fb2cf7d9588a4dd764b905397b877e7b20b44c30f82cfd836150"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumTagFilter.vue"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"863c45cacf30817285c8fe1c99fc9cfbf5d553f07ba6a66fd69d36711f8d324d"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/HeaderEditButton.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0991d828588c9c3e749191b8d3648a10f89765ebf345cf3e4cb155cb9e66a5f"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/HeaderFocusPicker.vue"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"10998913b7780ab53393a6880024787b5ea4182c999da3bc0c5df2cd0949f13d"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"78b7fb5d8ae3c9e4d475860085966c4c9684aabf175186a213a24ea4910c9271"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"eab57cba6f02f76ae25aa1c3d90815ade4a256e47d85b53b57fa1002b98295b5"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Cdiv\u003E: This \u003Cdiv\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a7fd7c58c25a2bae8dac3620943c61d968b544113b15438767aeada25c2927b"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Cdiv\u003E: This \u003Cdiv\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ThumbBuyMe.vue"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"8699cba80a28a29ccf967efb328cd535be5e2da2f88f646e00d031b655099be5"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Cdiv\u003E: This \u003Cdiv\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ThumbFavourite.vue"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4e3f367b603a43cbc49fad0f0e1de4a34720ad1d557d2270cbf8ffe35c54ae0"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/LigtBox.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f9e6590fede2a1279d7e3cf2e066952728cde2ed11a49fb0dd10fb932e222b2"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Cdiv\u003E: This \u003Cdiv\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/ColourSquare.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c26b865ce124068d4cd74b84de85f2c1e141dd7c1e528413484d4eee732c280"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoRatingWidget.vue"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"ace5d1f1e842ee2b8250c886a7f61b7c70351298be24a11e0066aa74bb06a603"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/GoBack.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"f13dbf1de9064585ae8a6cb4acd4b2624b80fcd624e7108207050e79ef4c21b3"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/GoBack.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a148c573dd0a249a4a52a03eec45d71cb02a6af90198c5745cf86f14dd35039"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/OpenLeftMenu.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"07f6e45525479a11e4d1f1d34a22976fdbaecf44289b52880df60aa1a3844e32"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/FixTreeLine.vue"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"de7563ebde0bfc61c8f054603e2f7b7d55520c043c58fc52b4e0e6f290626b2f"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/FixTreeLine.vue"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"0736a5c2416506afd12e3cb0a95f0816c1f91530767dc7917523d98db8a684bc"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/FixTreeLine.vue"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"05598281dd4b6887b1a914d0731709b531f373bfab41dca737a2e4dd5fa5f4a2"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/FixTreeLine.vue"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1b77d17a5ca5a33ecb23d5a502998882675a8615cc14c3a7e6900b539d5de54"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/faceRecog/SelfieClaimModal.vue"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"b78945e94d2e15ad3269a39544365af70c53dc83f78b742469ccfe8df1b4452e"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/pagination/PaginationLoadMore.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"adce00c4696ca99e6085797e165754dd1ed6e580506d9a4ed44c658f5c32f7ba"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/renamer/RenamerRuleLine.vue"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e0e32df5b3e9c525287f5a348ea5fc74003dd56d4e3354695934c1d61ce4a91"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/renamer/RenamerRuleLine.vue"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"160fd30bc32e4e02487521c21e6fc9edb7bef8e10d51f5b0de13a41ea063156a"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/AllSettings.vue"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5dbd4a9414284bd0438384806cf9e6b34a3664a31f90bc9ddb6c965d239c3b4"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/ConfirmSave.vue"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"22ac25b95faa1dab6e65f54e84462a449fe0286d2d53c70ef5596c5b4950c47c"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Ci\u003E: This \u003Ci\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/ConfirmSave.vue"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b4cc0d2b23320af114077b4def9d0d9f52ffc16a3a25b66c085d46d5940d573"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/CssJs.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"073aa04faedfbd224009ba8b0a7945b32e6cbf0746e4376e55a45ed2c7bafaaa"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Ctextarea\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/CssJs.vue"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"271e2dc3d6bb5a464b0a056e53bd39807f31798bf6185ea0a422d23e0ec177c9"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"df760682b36af5fa4661ec5a44a92cdf48726af900e46290c8487e367b9e0c15"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a384b6e01f4af3dcf3f87b085f3934c8edf7fb8a933e243d4ce6f089d267d22"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f99b5badef4ac636956ed94d29fe45f2ce259d24cc9e691ec0cc25653ab6616"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ee249d33f21c2fa8049556b15a00546659f66fe8422545c4a0f9ac695895c1e"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb19bc435a6f6545e74202a233bcfc27cae25136623101e5c047f2696527df36"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f66ca53a9be440e9b1c31f68bfb08640b867b3794d2b2dfceb28b846373da33"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"a38774ea8ff12d2122ec8f817a088b80cb35983d4a715353a69e94842274f695"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/Disclaimer.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"bee2abccf54c004915c1dddbda9d948dfcb580cf52a465e69a8c114bfdec8153"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/InfoSection.vue"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c1cd149d336db63b76e9a3bfde3372fa131ca490b8ddcce2581c4e34d36f54e"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Ci\u003E: This \u003Ci\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderLegend.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"a181b2fe2391400fe396f09146bc63f87433148ab1c3d49996523d3cb2ba291d"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderListAction.vue"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bdb8b04031c3b9bc12c1ae29fff315a1b5e5025616b6a927dd5d079ca6a3b9c"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/PaymentForm.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"8489c2ce3b2865d03dc8b5c9510f55ea8f14bf178e4748a089e290284836c45a"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/PaymentInProgress.vue"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6410d47a03d798a6e275bf02e093a919dacb3cb4bebb43c1f7d13acd0a092c6"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/ThankYou.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"ccbc0fd34e0a53aa4efe7261eb0d01e3be16d95ff8303e150a55781c69d6a7d6"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Ci\u003E: This \u003Ci\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/TransactionIdLink.vue"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"68c3aa66f4c4c3d8b37d1155aa5f2cd21af75ed30d92c796aa13ec9a96b6c19a"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/menus/LeftMenu.vue"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf064344e556e65d4eeb02204c4f36cbc8792c34d27f262c0633ae25f91b6b8e"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c6414721583c1c06b09309d4f1dc48b8a6e95209e02e6155ee3b3a02218c669"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"91c405cc6257bf6ec2437f76a1bf5872bcb57d2933a8464b9d455887aefde96d"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":242}}}],"partialFingerprints":{"codehealthFindingId/v1":"98295608c931988f54eb8bbc34773048dc59cbc8039947ca23cb1182fdfd6ac1"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":269}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b414a07ccfe847098e59d81fdb6f2b0c62c4d00b05331a251c1d007fec8173a"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Contact.vue"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"335c0f4fbdac541f1674f8d986025bb5bb93aa192688cfab8bfe65fa371ca4c0"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/LoginPage.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"947fbad5604266b8fcbe8341d6d581b9d8600a902c0127f6e0cbc05a7aea06b8"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Profile.vue"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"70b88a95915c9e622ea9d88028cdacb4144b6bc3aaff70804831c6202835f47f"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/RegisterPage.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"e99095d2119fe96f892c6f3ef4b5372049ac7189e03b2e9c3da58dfbe8fa8e2c"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/RenamerRules.vue"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0ccc3ddb644841864dab716b56d9ca95cc9d2b3e33bf5a80e8eae88e85df87c"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/RenamerRules.vue"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec864ea5a4ecc475f22b0ef9b15f70aaeea04ee8543f1909455e90d4f1118c3d"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/ContactMessages.vue"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b32989611dd009d70b2130a93ca5f6e5bf294987f03feb3fb7b4a5dbf223228"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/ContactMessages.vue"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7738942d35b5148dd7503aca3f7ecef7aa4a7f07bda8af42f4c560804cc5130"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/ContactMessages.vue"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb151944dc23a6980329b09dacd698fbc45e64a62180c675b53d0d01709b33ef"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Moderation.vue"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"d33b133c551cabb57d14ed23a7b40dd3dfeb615992a25214285ab7e84c0e33ba"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Moderation.vue"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"d81171e2cf16c5df0a0316312d0ca4feb634b8ad78ff73f78002bb5627f283d2"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Moderation.vue"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac711b0ad18444df5af21f6efa72e2c33f9d7f51cc5c26ea1be57abfb3020551"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Moderation.vue"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"c59ea7be829b18db51944160abf4306385ac7501391cfd3ee87405f6f506e814"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Webhooks.vue"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"1321808f4dbd4889325006916b97df2aeac61f3560c1ed64d0effb697e3099a2"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/shop/PrintPixelSizesAdmin.vue"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"161fe1fa13cb95afbebf272d3331f7c52e18cd6f7343b30ca66b19902ba39940"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/shop/PrintPixelSizesAdmin.vue"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"ece5c035de0cbe7afc975bea868d30c2668e2dae09677ad251aa27b964dee25a"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"7db7a8b206b674d0f766a7d107f15a6dacd865a26a9b08739c8266d8338bc816"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"b50175728026f3895c159f02d1a560f8922be1ed2aa0a9b75be8ef5e5d3fe243"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/People.vue"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"9361e8b5aded41bfbd50f442b2906ac01fbd7b77299bd20d74549bb6ec1fd9f3"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/People.vue"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"27a4108c2b48874b248ebdbcad93639d2d788cf9c6e8eb5c30510adce5fea0aa"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/People.vue"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1ba37a574bf4ec1a64da9d74f151b2944ef5cc049e35fc5a0ae88106a574367"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/CheckoutPage.vue"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"6350db748ca50c020dffc1632f31d16b48c4228fa7b41f18370a4b19c3120027"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/CheckoutPage.vue"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2531735ee6eb58b37a53c8135476fe425e4dc61a272425a55c480e68922f507"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderDownload.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"f81fbed7edb18bb6e3315725c46a5e85fa375a09900cf34ac41f1ac6f3155bb5"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Ci\u003E: This \u003Ci\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderDownload.vue"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba2c99e073798ca5989ac5a89beba0ae121313f562d76c7c765833bfca223dc3"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Ci\u003E: This \u003Ci\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderDownload.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3faa101fdfdad64f2ad4ac11a6a89596627cb7d16bf50e3ab00dda7598a98530"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderDownload.vue"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"5379d34295042395c970a54f138900b816a689d2290dcc396462b8fa101f0bb6"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderDownload.vue"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"36182dc84c04df170542d77f7f5dbf74df7a841d9c680d305c217a65506bcf2b"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderDownload.vue"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"6658548c38a3338a81af7bc260252ebe4d04291c8475eb81d409a0af8eb64b53"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderList.vue"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"34cac900a6087caba202e4a4602df5e33f9f6eec8ec6439c43cea4ae263d6b4f"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumMove.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"6018f9ee18e2c5d33291c9adb8939fd12221c023cd4da4b597e1adbb51132fb1"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumProperties.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"887b70245a39ed99f4c42438ef8ed66c383c66816673a8ab5e24d96cd4dc83e2"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumProperties.vue"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9fe13a89afe951eb2db67e2ab46b2e0a29d16af4f5a6f4ab89df328a3e0d8ec"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumPurchasable.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"913a5aec25d4b7a0157386bd683fdd5b2ff40cf9fb2f6068ad40ca5e695a9d47"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumShare.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a4255b01b1ce6f17f584268d100b184ec961e86ecb289d90b0e3b01260996ce"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumTracks.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"21bb9f80c233b9242200a8c2b4656e56017416ba365ae3a4bc29bb9de03a174f"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumVisibility.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"85ab783ed1366f9161337e03f366f741eb20db34eb6ec4871d3587756c7e3679"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/Fieldset.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"485a9df66d2ef2ef91a8d72ea20fec93cf6069634457c04ffa5829d2a6c30b55"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/PersonInput.vue"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2e44852dbe9d9202617cb8d195dac68cbbf8783ec57c10108814b28f8ea0bfb"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/PersonInput.vue"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"54c9720bae7ba97d63b341b6e9a68792efb2340e3d18476d9e10c384d4f67212"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/rating.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"067826c3589be05a5212a74d9175a6531f6c486af03c49704f2444f8e83fb1b7"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/profile/SetLogin.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fbb815f8c07b0cdfe73369b49d68d0bd3abe0bbc661b09c147efa3235da4f4f"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/profile/SetOauth.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"6de36ed96fe48dc8fce9c35be87db0ef06db847dc6da4f21331eaa7f642808df"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/profile/SetSecondFactor.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b2bec6b3ac11ef84905185034a3802a535cc7aacd44de6073f355fe15b134a6"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/profile/SetSharedAlbumsVisibility.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"0703d4a6fe3ab32ab3024a7f200e82f53f5fef1b5e0447cfaddbb24081e1871c"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"f38c102a33d81223beb6be8d71ebaad532dbec1dfb1cb676b6cc0eb03b853ec2"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"fdd106597fa3a87e2ba5cdc416294ee4103b6b84b4d8160f76a29d836f7f16cd"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"cde3b64df68b5f4f5881dbdd276283b10bb37c18a2c49c7cd4cd526c317240af"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"a20730341d30478038742158f40dcbf0a50b12c703149de9ac6acc34d640bc8b"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"acb86d3a4501df44dfae6bbc22362ff6f90a600012e1246ecb8c8714dd031688"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"048071e41f355c460581908d7ee662af13a36d0aa2617d2def7e26793584ea76"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6250eb123d04cbd1de754bf9dff6101c3b3464e8e76b47b7623c95da820686b"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"26749d8d8ec64413ef0b62da4f4c1b5c51b92cc53c56c8a7212344625c345da8"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"e008e37fe932b89f03f468d725ce5420ad473cc7cd10a381e1e9d9db0d5f9563"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"312dc1034cece7568ffd1ca3eb9d766cae318a43a208756eef021f88f47cbecb"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e0238feb2c9a0f46c8e1314bb2614dadb254f61ea09ba45c1717fac4a344854"}},{"ruleId":"AC2","level":"error","message":{"text":"Clickable \u003Ca\u003E with no accessible name: This \u003Ca\u003E has no href, so it exposes no link role \u2014 but it carries a click handler, which makes it a control. It has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"1169bc3d734afdb8cb62556c3f436537562516868b8dd392c0eabe814e960100"}},{"ruleId":"AC2","level":"error","message":{"text":"Clickable \u003Ca\u003E with no accessible name: This \u003Ca\u003E has no href, so it exposes no link role \u2014 but it carries a click handler, which makes it a control. It has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"880997f31b5f4b74b20e41734eb982995b8fc48c21c12868bfd0c94169749c3f"}},{"ruleId":"AC2","level":"error","message":{"text":"Clickable \u003Ca\u003E with no accessible name: This \u003Ca\u003E has no href, so it exposes no link role \u2014 but it carries a click handler, which makes it a control. It has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc376564c3692a71309cbfb57df8d6b67f8fe8dac6e04f70592b4c1278f39db0"}},{"ruleId":"AC2","level":"error","message":{"text":"Clickable \u003Ca\u003E with no accessible name: This \u003Ca\u003E has no href, so it exposes no link role \u2014 but it carries a click handler, which makes it a control. It has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"54cd2c49c28f42d758a54dc945e333f3c0ab8c4515e654c28dd725e0fa4163d2"}},{"ruleId":"AC2","level":"error","message":{"text":"Clickable \u003Ca\u003E with no accessible name: This \u003Ca\u003E has no href, so it exposes no link role \u2014 but it carries a click handler, which makes it a control. It has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"80d2bbb3a82064cd91aaddcffc8b16c94771925d9500f17bdf0d7040a852d319"}},{"ruleId":"AC2","level":"error","message":{"text":"Clickable \u003Ca\u003E with no accessible name: This \u003Ca\u003E has no href, so it exposes no link role \u2014 but it carries a click handler, which makes it a control. It has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7c16cb55765f58e090f970fbd530e1c8670b9cbf858f38d5e90f623b787bb58"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/HeaderEditButton.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b2e2e5f6bfed7a290dddfea6e24ce2d38ff7e3192d7ab5617ee131ba21695eb"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/HeaderFocusPicker.vue"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"f36b57b93ace3354b9be8c9cf7fdaf6809009e54b622b187f77e1759b7bf8e7e"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Cdiv\u003E: This \u003Cdiv\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"1be9e2e43ad4291fe0f17d786bc91f205934dacab6ded2ec1a4d3ef651fd991c"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Cdiv\u003E: This \u003Cdiv\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/ThumbBuyMe.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"54756505f4cea9a80bc7d698449ae21524c8f0b50da1e4717ecc98b1fd7642a7"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Cdiv\u003E: This \u003Cdiv\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/ThumbFavourite.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a7e0f3578fbd08f29ca9044f8318fa05d7c1f90f95c6c75148fbced7fecffe5"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Cdiv\u003E: This \u003Cdiv\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/ColourSquare.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"538193845c5edd10805c975c43f4506a959d215cac7753e2dd270bd7ec662e05"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoRatingWidget.vue"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"91d32586bc5a5be9299b3aa21a3ab3033cd1509753fd7cd1ddf6e647541d062b"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/landing/LandingBackgroundField.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"073150f24a9a43d9d723caecb46f273b4e83c195f7c0c0d8db89785cd245efe5"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/landing/LandingBackgroundField.vue"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"a387ebb1fd2dc729b0623d3a6547e4095d50147f95c3f7d4751fead35e5b5d7f"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/landing/LandingBackgroundField.vue"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb5b83938283f83247b046f27b4d845c71a4887eef7a05c415b109fe324a1bab"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/AllSettings.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6218123953d8d16287477716e788ce7567e947b8e22418c593be2bd32808f2b"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/CssJs.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fd0d1c2a5601d9e24015a040f71f6d8e2144d4b6c7dfd434a8a959f9a718084"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"43445c78d0d542018d59ab20a4f3eac018f0ed37b61d25aa31bfbf5145247fdb"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"2603606d27a6255305bde79fcbbb296b609cf92d545ebef32600d91e0e2bec13"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"b85945be5abdaf36b753d6a5a395cd8d967e30c22067edbe84e16026ce8e967e"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"1008219c2d97fbd242e9ebd1e78b2a6232b2e2782334a78e5e02007f8cc02b41"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"28690ce7e758cb22011ea64403acb5d2878ae4ef169201602776fc9e39b2daa1"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"036a26181d4b04466bf0474fc881abd178a358fed443e40e440040c27a9c2f58"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb3a63c893932df170779db83d822ae6e252f7aeedc0d1d1297bf64a6f1f9ed0"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/RenamerRules.vue"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c4e255688094ed10e559956cc3c29693c2e79d399764e11a8d4f99444ebfb4b"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/RenamerRules.vue"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"d26818993a1a051f2a34e99619a99a072215c05a55bdc4bf42ce63cd52e726b5"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/DesignSystem.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7bd5fb839cfb5ff8aaaa993e62e9b3fda059c0c2f1dde4e9258ea35e5495896"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/DesignSystem.vue"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea290c67324f021353842057292433e584466574c8b005f1b0aa466e3bb91997"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/DesignSystem.vue"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"31ee1ff4a977badea868e519717ac21b3d6b5efb974ceeb0f9cfae361c959e12"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/DesignSystem.vue"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cdfb0dfa89e64edefaea6d8666b90861da47d962acf969df8847a818918b558"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/DesignSystem.vue"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"595904732568206c845d4ab63466dd81fed6e6a87adc984b0cfec437f99d9f91"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/DesignSystem.vue"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"32b7356179c716b51e826164b0b11a4dc73cc0e786c3e110aad52a6c6fba120a"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/DesignSystem.vue"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2c614309cb8e5524447a6229fe2e9cc51958dcd798e98d7a81a1166a64d5ad8"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/DesignSystem.vue"},"region":{"startLine":181}}}],"partialFingerprints":{"codehealthFindingId/v1":"d25b6703165428326fa641979d0033ff502dfd6337800636a5aaf1369cc78289"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b1b0ddccebe6e0c9b88f28b49aa82f0f7f05326f1c22dc397a384c279817233"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"d77a91a5fc96a27b7f05cf2f5f1f1edb2701e5676e89f3a877d6ffa52c01ec72"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6e4fd02e28d575b71d64a86888511c11f097593418d6f994ad64ff74a4cb623"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fa57a80fcc22e4b87e6a354dfe7211aeb6acd175bac857c4cb9a159e394b832"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebb551f6514f071ba3415a968a05fb68028e5ab22ea5d46bf20c122ac6f1dcb0"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"87f429f8ba838249f82cbcf3346039107e85db9e3d89bd6e30250b2d25887207"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3e2dfdc6a0fd1b08acdcc0289c5bb8f59d98b078835c87971d0442beb0125e2"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"461360e249ced3ce1f8dbdb9a397e8b5823a614f29d8e3202752b0c3f86dc7bb"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"040e08c044dd2d17af876c90ec6adc60163ef666456977eb7946eaa11bf97796"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"72e44187b79bb74f36a6eb9f2873d1a69186697e094a470a7c05cc3901f0155c"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbcdf1f925d6ffd9162d3ca3eafc0c1148b3e6a46242b1cfb32167d86ddad485"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"349d477704f8924c6881190ddf02deb0768e2a088fbe4797ca581fe4783904bf"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"69153d6ea9e07f45b2e560fa7b77dd7390a1ecab024d9409f61a8d5f71243f6a"}},{"ruleId":"AC2","level":"warning","message":{"text":"\u003Cfieldset\u003E without a \u003Clegend\u003E: A fieldset groups related controls but has no \u003Clegend\u003E to name the group. Add a \u003Clegend\u003E as its first child \u2014 or, if the group already has a visible caption beside it (or the fieldset is there only to disable its subtree and carries no group box), point aria-labelledby at that caption\u0027s id instead, which names the group without rendering a second one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"17d55a737f14c014db9f13ee6ead253c5872ec792af31c5e65c3b52ab7383600"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":233}}}],"partialFingerprints":{"codehealthFindingId/v1":"87ba3cdc485bc40fd247c1315a39634a9bf2c551ac046813dae308d4ccf17386"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/includes/footer.blade.php"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc9d47fb656d56dec2d825be88d532fed3ab3722fa1280aed819cf8fcac27f24"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/includes/footer.blade.php"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"04870cf3f0399f04fae2e1e39546c75ec807d0266c228f62e77df1b4c0defe25"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/includes/footer.blade.php"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ca09aa728a3c316a2d34bd1250e28f3937565415441f093a2714aa340ac1c44"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/includes/footer.blade.php"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"73f8dd7e00a7d8c488f0bf0265ca66c0dbcc1e0570a8e3fd8d4da38cbd08aabd"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/includes/footer.blade.php"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce79ce9e9b49cbaaf5afa5b9b8a3cec5e5868506da884c526c7c06256654d8ba"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Ctextarea\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/install/env.blade.php"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1186bfdc90a44b95375e11042b0be1aa74a9773c33b22c31ea1fc06bc6df09c"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel for\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/install/setup-admin.blade.php"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e3aaffee210a1e14628a99247fb1fecdb88181cc542772db2dc1085daa3ddc5"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/install/view.blade.php"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"60aa98ede2cf527dff276995e7a01b171f5f10750e04097359a7a2d08fc1d56c"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/install/view.blade.php"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"71501a653fe5019f8c240e3d4a00dd25b2f43a8b41a04e85acb0fc602719b07a"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/install/view.blade.php"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"5751d4274246926735af387518851c992665552aef83bb5367e961a8f471cdc3"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/install/view.blade.php"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a6224547634525868e9abeecffb585e9f177989369b3bbfafac71c3b1ec7555"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/install/view.blade.php"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cc3f1fbc2748c4cbf53bdb0ec207de277314b7572e780a8b82b1befb848a0ea"}},{"ruleId":"AC2","level":"error","message":{"text":"Link with no accessible name: A link with no text, aria-label or labelled child (e.g. an icon-only link) has no accessible name, so assistive tech can\u0027t say where it goes. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/install/view.blade.php"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"085b4f27a82a17546424b74ea44a329117492d10e7f758c65d894704d0548376"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/update/error.blade.php"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"48b6dc887acb53336b4125f443b10e9ed179492a671eaea75cde0e265d097aaf"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/update/error.blade.php"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"869cae1ea3586830302bc30c53eef617da350d1b58e810e4844dabcca9a8b603"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/error/error.blade.php"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3471116e73c538d66d6368217d54bed606c31c2987fcc7850d4cec3fd79b4c2"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/error/v1-is-dead.blade.php"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"714584fa47432959843a28c7c66d53d9242879186806c5f9745f19bc7e22a5b9"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/health-up.blade.php"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"491db46a6f97a475ff603a3b42958fd712389a6ea296cc841548069df05f0f16"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/install/view.blade.php"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec94900fd2a1b9fbc5aa7a4f91272b6d1c1b391fc2518c77b1424b779d095b25"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/update/error.blade.php"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"c86b5920fe37d3da764ad8d3dc2dbc04b66a0ac5cf6d65285017a54957a0c925"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/update/results.blade.php"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"74cde1b27d31eeba138cd1e812f5af6ab4534312f07fc7921f5856f08113aab2"}},{"ruleId":"AC3","level":"error","message":{"text":"Document without a \u003Ctitle\u003E: A page with no \u003Ctitle\u003E gives no name in the tab, history or screen-reader page list. Add a descriptive \u003Ctitle\u003E in \u003Chead\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/vueapp.blade.php"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"16cf42e8acfe5295c41d1a51f26f27e1f04232c5f38956f26364790d322ceca4"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/vueapp.blade.php"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"14db00e5640b1d471a205a2a0f26045553f9ab62518d040938d210b494c76436"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"simple_error_template.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"77cce033d487683e6c0ceb660775f20d749a1026d3d8ba7dd412f67c90097647"}},{"ruleId":"AC3","level":"error","message":{"text":"\u003Chtml\u003E without a lang: The page declares no language, so assistive tech can\u0027t pick the right pronunciation. Add lang (e.g. lang=\u0022en\u0022)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"vite/index.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d2de75d1d968387f704aed7233ec0f680c8d0981119b8ccfb12511cbe91395f"}},{"ruleId":"AC3","level":"error","message":{"text":"Document without a \u003Ctitle\u003E: A page with no \u003Ctitle\u003E gives no name in the tab, history or screen-reader page list. Add a descriptive \u003Ctitle\u003E in \u003Chead\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"vite/index.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a4233c3f9e6375d833d28aa774ca2d3426cd4ebfa359aed07553d22ef181bb5"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"vite/index.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"f072483fa414c6bdf5d450a89936cfaa348a287fb986e8948b8f959ec5efa0e1"}},{"ruleId":"AC4","level":"error","message":{"text":"Focusable \u003Cimg\u003E isn\u0027t keyboard-operable: This \u003Cimg\u003E carries tabindex=\u00220\u0022, so it is in the tab order and a keyboard user will land on it \u2014 but its behaviour is bound to the pointer only, with no key handler. A tabindex makes an element focusable, not operable: Enter and Space fire a click on a native \u003Cbutton\u003E or \u003Ca href\u003E and nowhere else, so this can be focused and never activated. Use a \u003Cbutton\u003E, or handle Enter/Space in a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/components/EmbedWidget.vue"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"253acb764625361282172e7c8b42ba74f0b03ea5cddb5cc393b7e4b7ac28e959"}},{"ruleId":"AC4","level":"error","message":{"text":"Focusable \u003Cdiv\u003E isn\u0027t keyboard-operable: This \u003Cdiv\u003E carries tabindex=\u00220\u0022, so it is in the tab order and a keyboard user will land on it \u2014 but its behaviour is bound to the pointer only, with no key handler. A tabindex makes an element focusable, not operable: Enter and Space fire a click on a native \u003Cbutton\u003E or \u003Ca href\u003E and nowhere else, so this can be focused and never activated. Use a \u003Cbutton\u003E, or handle Enter/Space in a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/components/EmbedWidget.vue"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2b1cccdb4cb54129af027551a5a6ff62e10ce6e7d9c3c40315cf09a6237cba0"}},{"ruleId":"AC4","level":"error","message":{"text":"Focusable \u003Cdiv\u003E isn\u0027t keyboard-operable: This \u003Cdiv\u003E carries tabindex=\u00220\u0022, so it is in the tab order and a keyboard user will land on it \u2014 but its behaviour is bound to the pointer only, with no key handler. A tabindex makes an element focusable, not operable: Enter and Space fire a click on a native \u003Cbutton\u003E or \u003Ca href\u003E and nowhere else, so this can be focused and never activated. Use a \u003Cbutton\u003E, or handle Enter/Space in a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/components/EmbedWidget.vue"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8dec8756ef1715c758726587e0a0bbaa8633a0e77dd8c393a9d1eacbf69c872"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cli\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/AlbumEdit.vue"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"afe4b07a3c199b5d54095fdbfae78589c027204f3282fedd63becb7fd505af1f"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cli\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/AlbumEdit.vue"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"79e2c5c4f2148998664b30c17b3c94f00e1c8077c3ee241b17980f8c842bf218"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cli\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/AlbumEdit.vue"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3e39715a9eec1693e81a19178f6d89b4197df5507f4bcc9ef647e6c5018df67"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cli\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/AlbumEdit.vue"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ddb6e8b8d8c128a3ebd931422af51abc49e70beb0b12e2b405a141b6fe8ad60"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cli\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/AlbumEdit.vue"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2e58293ca4b0754d27669883a1d011993d11bb4f2081112bb33b8e0ea7dc648"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/auth/LoginForm.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"b70593e6383656f627906f0c9691fb87c80849010aaff9d179e266c75f8ae613"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/sharing/CreateSharing.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"62600c61500d8d6de6068a08ca2b3f6875506aa186df041f22221829d0d51815"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/upload/UploadingLine.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"88cdc9a93b1ced6885bbda1ca9451df96d0c754c72a82d1db8ee325c058255e9"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/PersonCard.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"122049296f65dc2f8c682fef9099c421bb9496a9f6f7f02018406cecd58e3cc1"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumListItem.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"f43a08d69dcdb4cfd9ca53ba86044dc572f2a32f31e1d2eb24de4a828c0b5fb7"}},{"ruleId":"AC4","level":"error","message":{"text":"Focusable \u003Cdiv\u003E isn\u0027t keyboard-operable: This \u003Cdiv\u003E carries tabindex=\u00220\u0022, so it is in the tab order and a keyboard user will land on it \u2014 but its behaviour is bound to the pointer only, with no key handler. A tabindex makes an element focusable, not operable: Enter and Space fire a click on a native \u003Cbutton\u003E or \u003Ca href\u003E and nowhere else, so this can be focused and never activated. Use a \u003Cbutton\u003E, or handle Enter/Space in a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoListItem.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"1926fd0f4a5c9b1f9236215b0edd0da607e4121edd4ca950dfab51806a1c38d6"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"daa97ac7852acb388f5b99aef306954759a7e8b3f1a777b3c45c324619825925"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"7bf0fa0788b0b908b8837e2aacc3e1ad45e4c318c652b30ee8fad53f5803d18c"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5474eab9411c7b65b6862279966b6beadc6db4ecaf8c3728aeae6167e72f69d"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"492df1de7cd63072512bd5524da82d1d2ce24f6692da6c607b9ebe526a4dbd1a"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"7525f6e7507427a26afc377c4a31b1adc411da363e61a555f26d4df7081b7af3"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"efdca877cf137a8385fc111281d17cd83b975e9b92e34fbb418def30ac86aba1"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/PhotoThumb.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b98d94c01ffd71dbddfa719c494b321e5734ca7cc6f937d11a242fe43200474"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ThumbBuyMe.vue"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c411e28148f01417a861f22287bbebef506b160f1dc43759b60553d3c37560e"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ThumbFavourite.vue"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fe2a11156de464bbbd10bf437a170160158083a006bdb0e946a378b062e1a8f"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/Blur.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"02fb9bcf64a3f332b84b5168ad9657fabe8131768cbb3af4a49845f9194ac3fb"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cimg\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/CarouselImages.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"9868086dd75997b3c4580a948d38957062cbaa9e3a35e3ada2cbbc21fbff0911"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cimg\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/HeaderImage.vue"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"54032c5e3c867cb552918199f78553077c492ac9d7e4fe3b3f7c2ba36eaad131"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cimg\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/TopImages.vue"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"3efc08e02e10bf263858160413640543f5f79a6147ade99e0febd46f7e2afeee"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/ColourSquare.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f6303ecd1eb7b873e7334dd447c7d6ef41147a21e2b1fc5e709e77502ad10b6"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/DockButton.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"921e4170de14f4994b58f2ee2d1118ed41c5435d8171d553c61962f4547e4944"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoBox.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"2211c9c7c805947a55158d4aa729e5163f4aca34f43ecc7107112d621a8f1f86"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/timelineModule/TimelineDates.vue"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"478a4b5931cfe4249d36775fe08eb77489f9196bc0a01370fe5e94546639f306"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/faceRecog/SelfieClaimModal.vue"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea30a95dd2a6d42d013578d3964f7ae133185a96c07767660edd4f3d3a807a76"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Ci\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/ConfirmSave.vue"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"0781c672fc60c3e1acae9d6c5016f540494cef6fd0d77b2bcb0535b9efaa731c"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/statistics/Activity.vue"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e0c61bad334dda6c4837fffd3bef06b1073f8ee313eb4834e885da41a2118e3"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderDate.vue"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"cda4b12a4dc0299718d447cd54ca0cd841aa85cdc001184348abaf821b20bd5e"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderDate.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7eb96c401bcb5295f04ab3e5e51cfe971143615a760df9c9909ffd9ecb48e3a"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Ci\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderLegend.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a6d70fcb986f17980479ebce34b82c1d7f1bc2956263e26b6ffcdd7e96c0f24"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Ci\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderLegend.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a24674416ad920b34049c97b8584a87aa1fa89ea89a5c8e60dd755cbe6346fe6"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/TransactionIdLink.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"23d3260ad6e4f2822fefbdcd64808d8d33410c1a5c1a64f7e98e8e4d0e7c5421"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Ci\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/TransactionIdLink.vue"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d3f6132c42b5b0836bd7306c323277d7f55c09d07e96ab4fa5dcba9df0c46b1"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a \u003Cspan\u003E nested inside \u003Cbutton\u003E: This \u003Cspan\u003E carries its own click handler, but it sits inside a \u003Cbutton\u003E that performs a different action. A keyboard user reaches the \u003Cbutton\u003E and activating it runs the \u003Cbutton\u003E\u0027s handler, never this one, so this action has no keyboard path at all. Role and tabindex cannot supply one: HTML forbids a \u003Cbutton\u003E from containing interactive content or any descendant with a tabindex, so the browser will not put this element in the tab order however it is marked up. Move it out of the \u003Cbutton\u003E and make it a sibling \u003Cbutton\u003E, so each action has its own control."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"b07868f0af136ef3242f0069dd1777c957bf1edd2a6b57c911bd91674222a3de"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"c86019e8391c1ab0a30b97f076c8020d60b165ea16d573ac6abc5058c93016f4"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":259}}}],"partialFingerprints":{"codehealthFindingId/v1":"119ec2d2f938a5972d038f71dd6b5156b026b95bcb8e3b9285a598d41ed61eff"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Ctr\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Moderation.vue"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd7415560c096aa989b6ba4cf7fd235ff0b341f58af63fa22ca7352dc14b3694"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Moderation.vue"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"e70f3a01b72e5ce44b6f18ab6ed295806fc9c40f0dd4ec138a2a45f1bcbeab72"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Ci\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderDownload.vue"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"555563263f61b945193a6177736395f9a7ab69710a0f9aba311f40f855c40ab8"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Ci\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderDownload.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"69af60c07fc6bcff380f1d4f0cf081695af3b8d4785d0c08a90083cf41526994"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoDetails.vue"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"527a4704dff620ca0012e609d7b4b7a770274a817ef51fdb73ce1be4df409be5"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumProperties.vue"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"fff25484b9d6f66b0ed618bb5c90c57d4adfbaa442aac577f3e4b40297d22650"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/auth/LoginForm.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"501fdf5cc64ea1c05d0e6de62fc207e7bb8982a75b737418cdd97c3ebd92347d"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/upload/UploadingLine.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5b99672014968a460131d82b9136219d8e29a005dfc2d0ed2c4155a00b5a108"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/PersonCard.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"cff7967fd23ee97e8432fb43504b3c44138c9f7b18221a1aa00925e80b41ed9d"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fc413da839ab59ea0718ccdc21a2c4aaca338e59f0d83f5e7a9242948ebf6ac"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"1889d5402de2d2eace372611836fbd4155ca0320ab43a9e5368b026cd1e5ac56"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ef5f00083acf0da6038373551313528458d86e51801d8d6afc4201c2d1bcc47"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"78a40583f991d3d32ef43b31fc2f86c6b2db0563d7371c587a1b261927a3dd47"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"654669c3731dd585aab2e3501d1276b779c397fffcfad5866fb0d3f2d5fca572"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"f36ffe6d29d609e6f178fd759367030da842a2f7e20c7b109ae78ae9e3b9c5f9"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"5327de0ef6e7954614e9c84014d8d50f170db4a0c3bb76f5bb92554b2771b269"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"b11b90ff5d2872e1a4d9aef71a3cbd90a3f1d9f04527892dddf6c71fc2e7fbd8"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a39b2413a008daac77dcbe5634080da4d08dc05e864983330dfb5593c9d32fc"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c9acbd637377099ead153519d075b8d0845b66cfd1407b3526adf77e4cd4df5"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumListItem.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"824164f4041a9e9fd2d8c28442500cec2be19349d03d94d83905db3bf0f02880"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumNavTree.vue"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba78492c6dcd248c5d544e0e3e5f60ead2d27b77cded1a4411b2eeb283d38b19"}},{"ruleId":"AC4","level":"error","message":{"text":"Focusable \u003Cdiv\u003E isn\u0027t keyboard-operable: This \u003Cdiv\u003E carries tabindex=\u00220\u0022, so it is in the tab order and a keyboard user will land on it \u2014 but its behaviour is bound to the pointer only, with no key handler. A tabindex makes an element focusable, not operable: Enter and Space fire a click on a native \u003Cbutton\u003E or \u003Ca href\u003E and nowhere else, so this can be focused and never activated. Use a \u003Cbutton\u003E, or handle Enter/Space in a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/PhotoListItem.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"92dd908082161bb36a259e48767185e8b48041a09d9848b7ceb79e7808d07664"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb3fa635beee1292772209dc671c5540674b7a1bfeda5e26511ccf6dd5f0c3d6"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cdf38e603314cf65701044de0ed4efa32011930fc7c2e3f3b20999434e7d884"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"130103bedd40013792bb823bf501e0da0a82a9b480688c018ee19c1f871072a5"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"2efe834c5a812f3129c4ac4aa7563def09ad5f28903595a6dcbc0d09cc64b653"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"e118f0d636de098c548c3222cf087ff67c9568be03da0b043704371384e31a02"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2f01316b99f7ee468bf8e38194eae1eaaaf330b03ad06253f7035672538fd3c"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListItemVirtual.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"2bfd071fb2bb5cb880b79ee0741c20eaf1273584ded355f45b9a7a47613948ea"}},{"ruleId":"AC4","level":"error","message":{"text":"Focusable \u003Cdiv\u003E isn\u0027t keyboard-operable: This \u003Cdiv\u003E carries tabindex=\u00220\u0022, so it is in the tab order and a keyboard user will land on it \u2014 but its behaviour is bound to the pointer only, with no key handler. A tabindex makes an element focusable, not operable: Enter and Space fire a click on a native \u003Cbutton\u003E or \u003Ca href\u003E and nowhere else, so this can be focused and never activated. Use a \u003Cbutton\u003E, or handle Enter/Space in a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/PhotoListItemVirtual.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"6926c0d4d541e51131f352074cf3de74a097b659a254fb721076fb7e1fc4e9d6"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/PhotoThumbVirtual.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"851809a65df9278ff6127befb5e4295792ccd9ec0c73e4b18a3bfe05d3150347"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/PhotoThumb.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"4aa5aad89df52b6fb2cb0c0c03a05915b8ac0e4c84a434d4aed986c35280f559"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/ThumbBuyMe.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"d90bede494d63edd9df30a0f55a30847ab3a9762c7b1d21e3d1c1fe53326400e"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/ThumbFavourite.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"411980b5e537dd964e44cefa785fd44172f4306aa15cbf07b455a03355531a08"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/Blur.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"08a43de2e3addac836c80d4441ed7e74e2edf51661d424247768a4460a787572"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cimg\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/CarouselImages.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"e75edafe3e27c0b853e09420c331bcc23c741bcd397f01037e5a7416409cae6b"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cimg\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/HeaderImage.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"da5cc8ad7e43b213575ea1d572d51431eb4cc3b7a19ea297cdb3d39694fb1541"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cimg\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/TopImages.vue"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb85216b950f35899e64ea33128517023635e7390dd123bc5c36d484aa7bf8ab"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/ColourSquare.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"082a1a57f60b9a50c94da88e00ab3d6eea3656da4479ae5b5df50850a39bf98a"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/DockButton.vue"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"e37841f5ecfe966162f2bc421ab670c5c9128579689ccfec0d12fa12d1dcc869"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/timelineModule/TimelineDates.vue"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb543b66eced3c3d087b795a48b681f445f75ed1e076f8e8600ff607510d5528"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/OrderDate.vue"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6cc33055d7c88258afd6f036d241922fd4f5392f330f168c69e7422f289c3fe"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/OrderDate.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"7cc57d06050b94d2b30f5075d5f9347c84be26c67a2efb8127f96e705fababa5"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/PaymentForm.vue"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"026e5dd67da63581ecf2688db404d87d41902979be536f12d0c4df169143378d"}},{"ruleId":"AC4","level":"warning","message":{"text":"Anchor without href: An \u003Ca\u003E with no href, role or tabindex isn\u0027t focusable or keyboard-activatable. Give it a real href, or use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/TransactionIdLink.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"b20fc1ccda1e848c18c3538bff0aa0bfe8f90fe9f6f45b3db3f44d166fbc99e9"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/FixTree.vue"},"region":{"startLine":119}}}],"partialFingerprints":{"codehealthFindingId/v1":"95cb4bd3b1d04294be85ec2a985433a9099a8bd65724a574883feaec334539e7"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/Moderation.vue"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"884a283c28ce4ba625e67b3deefe7e81fceef94c86536ab447bc4b4d6cd836fe"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/NsfwFindings.vue"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"247de72140f1ce0d7bebae274f4a002318de321bbbdcfb2fa23a0f54b8b41cf9"}},{"ruleId":"AC6","level":"warning","message":{"text":"Focus outline removed inline: \u003Cbutton\u003E takes keyboard focus, and its outline-none utility removes the focus ring with no focus-state ring, shadow, border or outline utility in its place. Add one (e.g. focus-visible:ring-2)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"29298a51d8e82c4baa3a25be1754a1e8d8d2218b839c5ac62f2c3af48d8ec487"}},{"ruleId":"AC6","level":"warning","message":{"text":"Low contrast Tailwind colour pair (3.3:1): This element\u0027s Tailwind text/background colour utilities fall below the 4.5:1 WCAG AA minimum for normal text. Pick a darker or lighter shade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoRatingWidget.vue"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"96c34826f392df9850359facbf2f976ce44f5cd25b0702fcfc6a4b868a421de4"}},{"ruleId":"AC6","level":"warning","message":{"text":"Low contrast Tailwind colour pair (3.3:1): This element\u0027s Tailwind text/background colour utilities fall below the 4.5:1 WCAG AA minimum for normal text. Pick a darker or lighter shade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoRatingWidget.vue"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"49c7cf2828f33f87f418ee9107b57d1ab89270557aa97663441a3d7f039e2a83"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: \u003Cuicon\u003E moves \u2014 its \u0060animate-bounce\u0060 utility runs with no motion-safe:/motion-reduce: variant \u2014 and nothing reads prefers-reduced-motion for it, so a motion-sensitive user cannot turn it off (WCAG 2.3.3). Gate it on @media (prefers-reduced-motion: no-preference) or motion-safe:."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/landing/LandingPortfolio.vue"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e99fd4eac404cde34240ca9a4fab0c199662f18b957bea19bc032f918a6534b"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: \u003Cspan\u003E moves \u2014 its \u0060animate-ping\u0060 utility runs with no motion-safe:/motion-reduce: variant \u2014 and nothing reads prefers-reduced-motion for it, so a motion-sensitive user cannot turn it off (WCAG 2.3.3). Gate it on @media (prefers-reduced-motion: no-preference) or motion-safe:."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/health-up.blade.php"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"af5c9a361981c9e095a5f0660b9baaabf33ea871aaa14be15049abf212cce73f"}},{"ruleId":"AC6","level":"warning","message":{"text":"Low contrast colour pair in CSS (3.8:1): \u0060html, body\u0060 sets color: #777777 on background-color: #1d1d1d \u2014 3.8:1, below the 4.5:1 WCAG AA minimum for normal text. Darken or lighten one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"simple_error_template.html"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e14021d63e0d700a78b5ba74ad6b0d076663b7486f090e02ac2d2eeaf77947d"}},{"ruleId":"AC6","level":"warning","message":{"text":"Low contrast colour pair in CSS (1.6:1): \u0060.step__icon\u0060 sets color: #fff on background-color: #cacfd2 \u2014 1.6:1, below the 4.5:1 WCAG AA minimum for normal text. Darken or lighten one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"public/installer/assets/css/style.css"},"region":{"startLine":3928}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd1499e8e821e4006cd17c5ed0eb5a348551a9c9475a76ac38f178de4d0cf812"}},{"ruleId":"AC6","level":"warning","message":{"text":"Focus outline removed in CSS without a :focus replacement: \u0060.p-overlaybadge .p-badge\u0060 sets the outline to none/0 and no visible :focus / :focus-visible style for that element replaces it in this stylesheet, so a keyboard user cannot see where focus is. Draw a focus ring (outline, box-shadow or border) under :focus-visible."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/menus/LeftMenu.vue"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0b1c3b08f9ffab6b1fafa575ceae9e05b97bb7483f4d380700a821945bd4c06"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: \u0060.lychee-page-enter-active\u0060 moves (\u0060transition: opacity 0.18s ease,\n\t\ttransform 0.18s ease\u0060) and nothing reads prefers-reduced-motion for it \u2014 no @media (prefers-reduced-motion) rule for this element, no reset this project loads \u2014 so a motion-sensitive user cannot turn it off (WCAG 2.3.3). Declare it under @media (prefers-reduced-motion: no-preference), or neutralise it under reduce."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/App.vue"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b4c49f510dd5d5c22353ad81b3713ecb6d44f417c09c82b13309897eaf708bf"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: \u0060.animate-landingAnimateDown\u0060 moves (\u0060animation-name: landingAnimateDown\u0060) and nothing reads prefers-reduced-motion for it \u2014 no @media (prefers-reduced-motion) rule for this element, no reset this project loads \u2014 so a motion-sensitive user cannot turn it off (WCAG 2.3.3). Declare it under @media (prefers-reduced-motion: no-preference), or neutralise it under reduce."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/landing/LandingClassic.vue"},"region":{"startLine":144}}}],"partialFingerprints":{"codehealthFindingId/v1":"b83dc356ce62349d5cf177f3d7515d78f518fca0f63f97f23905f3237d152f9d"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: \u0060.loading-ring\u0060 moves (\u0060animation: loading-ring-spin 0.9s linear infinite\u0060) and nothing reads prefers-reduced-motion for it \u2014 no @media (prefers-reduced-motion) rule for this element, no reset this project loads \u2014 so a motion-sensitive user cannot turn it off (WCAG 2.3.3). Declare it under @media (prefers-reduced-motion: no-preference), or neutralise it under reduce."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/LycheeLoadingIcon.vue"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"22a07f6c72c919013bd7886322d71d6c67a02f7655dd33ad1e2a6c80af019a8c"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: \u0060.slide-next-leave-active\u0060 moves (\u0060transition: transform 0.5s cubic-bezier(0.165, 0.84, 0.44, 1),\n\t\topacity 0.2s cubic-bezier(0.445, 0.05, 0.55, 0.95)\u0060) and nothing reads prefers-reduced-motion for it \u2014 no @media (prefers-reduced-motion) rule for this element, no reset this project loads \u2014 so a motion-sensitive user cannot turn it off (WCAG 2.3.3). Declare it under @media (prefers-reduced-motion: no-preference), or neutralise it under reduce."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoPanel.vue"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6451d0ac23aec7f4f4fbc4b32751b4442ffca80fa633017719a822e05d5785c"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: \u0060.slide-previous-leave-active\u0060 moves (\u0060transition: transform 0.5s cubic-bezier(0.165, 0.84, 0.44, 1),\n\t\topacity 0.2s cubic-bezier(0.445, 0.05, 0.55, 0.95)\u0060) and nothing reads prefers-reduced-motion for it \u2014 no @media (prefers-reduced-motion) rule for this element, no reset this project loads \u2014 so a motion-sensitive user cannot turn it off (WCAG 2.3.3). Declare it under @media (prefers-reduced-motion: no-preference), or neutralise it under reduce."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoPanel.vue"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"b08a1accf9c3c51aa815c3843c24d950267686ffe0f8fb27c020a1a244fbfd90"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: \u0060.animate-landingAnimateUp\u0060 moves (\u0060animation-name: landingAnimateUp\u0060) and nothing reads prefers-reduced-motion for it \u2014 no @media (prefers-reduced-motion) rule for this element, no reset this project loads \u2014 so a motion-sensitive user cannot turn it off (WCAG 2.3.3). Declare it under @media (prefers-reduced-motion: no-preference), or neutralise it under reduce."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/footers/LandingFooter.vue"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6d235a20c94bf5538bda9c572213e3ec0d44b71dfe814ad1d43c0fe0877f20d"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: \u0060.animate-landingAnimateDown\u0060 moves (\u0060animation-name: landingAnimateDown\u0060) and nothing reads prefers-reduced-motion for it \u2014 no @media (prefers-reduced-motion) rule for this element, no reset this project loads \u2014 so a motion-sensitive user cannot turn it off (WCAG 2.3.3). Declare it under @media (prefers-reduced-motion: no-preference), or neutralise it under reduce."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Landing.vue"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"f000b3e57686cd735fa416cedaa0554964b0727d8d45736e56ad9bd403e9762a"}},{"ruleId":"AC7","level":"warning","message":{"text":"Accessibility enforcement below the top rung: No accessibility enforcement found \u2014 no a11y linter (eslint-plugin-vuejs-accessibility) and no axe/pa11y/Lighthouse in tests or CI. Start with the linter to catch issues at author time. What was searched, so you can tell an absence from a miss: the 669 markup file(s) this pass actually assessed, the linter configuration checked in beside them, and this repository\u0027s test and CI files \u2014 matched by name against the accessibility checkers this dimension carries. An audit run outside the repository, a hosted scanner, or a check whose name is not one of those, is not seen here."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d46019b86eff5ddad9db289e6802ac158899e980df54c34f67722442787ead62"}},{"ruleId":"C2","level":"note","message":{"text":"Anonymous-heavy surface: Public opt-outs and open tables (6) outweigh guarded routes and protected tables (4) \u2014 review whether the open surface is intended."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"fe36ed341d024b5c2f9815c8c57995cf558c1d2de2ca9e7139e1c48695961190"}},{"ruleId":"C4","level":"note","message":{"text":"Partial data-retention evidence: A retention mechanism is present, but the data-lifecycle is not yet complete \u2014 missing: an expiry limit \u2014 a declared maximum age / TTL after which the data is no longer kept, a documented retention period / data-expiry."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e6c843eccaff7ffcfe5241125b74768c2364055ab6678b12b10d47f44086afa4"}},{"ruleId":"DM11","level":"warning","message":{"text":"Constructible in an invalid state: PhotoResource: \u0060PhotoResource\u0060\u0027s public constructor takes \u0060album_id\u0060 as raw primitives, and neither of the two things that would make that safe was found. What was searched, so you can tell an absence from a miss: for VALIDATION, the constructor body was scanned for \u0060throw\u0060, \u0060Guard.\u0060, \u0060Ensure.\u0060, \u0060ArgumentNullException\u0060, \u0060ArgumentException\u0060, \u0060CheckRule\u0060 or \u0060Requires.\u0060 \u2014 a guard reached through a helper method those tokens do not name is not seen; for a FACTORY, only this type\u0027s OWN static members were read, and only names beginning \u0060Create\u0060, \u0060Of\u0060, \u0060From\u0060, \u0060New\u0060 or \u0060Build\u0060 \u2014 one inherited from a base type, one on a companion builder, or one called \u0060Parse\u0060, \u0060Make\u0060 or \u0060Rehydrate\u0060 is not seen. If either exists, this row is wrong. If neither does, a caller can build a \u0060PhotoResource\u0060 that breaks the rules it exists to enforce, and every rule downstream then has to cope with a state the model said was impossible. Guard in the constructor, take value objects that validate themselves, or make the constructor private behind a \u0060Create\u0060 that can refuse."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/PhotoResource.php"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab075c6859427bbd757e35cde0b0e3264d620170fb998ca04371aeab12a5b6e8"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: Album: \u0060Album\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Admin/Maintenance/Model/Album.php"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2fad593e01579ef9a59050864c506033ed61b81389fe43bbdf811dba9c2d6bf"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: PhotoResource: \u0060PhotoResource\u0060 is an aggregate/entity with 30 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/PhotoResource.php"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"a929c140d1608dfcfbdbc1fac33928cb24b3854f9d16e9dc4b0e851120a26ec5"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: AccessPermission: \u0060AccessPermission\u0060 is an aggregate/entity with 2 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/AccessPermission.php"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"07ea07b3c62b6abf9ed65bbdac452ea158c06f771be3696adaafe3c71c2b4ec3"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: AlbumSizeStatistics: \u0060AlbumSizeStatistics\u0060 is an aggregate/entity with 2 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/AlbumSizeStatistics.php"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"723e0fa08d602642b004f5fc720c7ba0c3772273abfb680e77faf2a452708222"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: AlbumUserThumb: \u0060AlbumUserThumb\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/AlbumUserThumb.php"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"47f5cc6170acbdf830c0943d76c4fcefa8e24947bef3394cb87d9251e3f3195d"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: Colour: \u0060Colour\u0060 is an aggregate/entity with 2 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Colour.php"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"37d468706583f4926bf740eb97e9cb680bd8b8b6f704bbe625bcc9b7ac7dba56"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: ConfigCategory: \u0060ConfigCategory\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/ConfigCategory.php"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"be6c84b311e4e47f48dbd4481e7c7c5e06c2abc1d486667a18e39a1f92d96b71"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: Configs: \u0060Configs\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Configs.php"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9db06a732d6a455ce6f99c42d83886ce151dc4bf7f91162b1d9e95da7479546"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: ContactMessage: \u0060ContactMessage\u0060 is an aggregate/entity with 3 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/ContactMessage.php"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa3ccb77cd42a40ae3576505e1f85570384e442a6d8ec5a7fe989b486d1942b8"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: Face: \u0060Face\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Face.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d546383a6865c46df1a3f96d15fddaf05dac9c8404960ad7a020df895bbc62a"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: FaceSuggestion: \u0060FaceSuggestion\u0060 is an aggregate/entity with 2 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/FaceSuggestion.php"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac3d9a7e684548ccc381c531141867d3d0dcda5df694197c30163cb8009f8a54"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: JobHistory: \u0060JobHistory\u0060 is an aggregate/entity with 4 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/JobHistory.php"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"bceef09d4636a28ac4e13a1d8e48d48be70bea28cdff929fa835cb6d8a354e6d"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: LandingFeaturedItem: \u0060LandingFeaturedItem\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/LandingFeaturedItem.php"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"e169fc1805ea5a90100251fa0e4b14bd8244ca22b888f689b6ad0084bf39147a"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: LandingLink: \u0060LandingLink\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/LandingLink.php"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"52142ffb0550ee74d600ebe6fbe572d145fe83d8164ff37c79cb960b2f50cdd7"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: LiveMetrics: \u0060LiveMetrics\u0060 is an aggregate/entity with 2 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/LiveMetrics.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2a2811ecac1f7f26e96705a982f8f72656e98f6fe4ea46a46c6933343ce51c0"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: NsfwDetection: \u0060NsfwDetection\u0060 is an aggregate/entity with 3 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/NsfwDetection.php"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f8f03658ed13b1d9659af84c8c5b6ded189895986e1647b7fe27cbe5294ac29"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: OauthCredential: \u0060OauthCredential\u0060 is an aggregate/entity with 3 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/OauthCredential.php"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2e15ad059f77613d442c35630f923ed9baaf153ec9ab49bff6d014863c8e082"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: Order: \u0060Order\u0060 is an aggregate/entity with 3 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Order.php"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"57a219e6a104b72ed6e7508150512e41d57dd116e8d0feb3cda82f52cef9b9b5"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: OrderItem: \u0060OrderItem\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/OrderItem.php"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"74ea6e216b09fc32a0985679318b5f1445455550fb4805f3643aa5b4989a6f13"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: Palette: \u0060Palette\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Palette.php"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"a82f55f650a85b6c4e837bee51116810266a9b6cfec18a48f903a6bebf7ce9f7"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: Person: \u0060Person\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Person.php"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"58deebb0f7495d989c5e1e340c4ef6cd4ccafa6081e50f03e437c38e3ae193c4"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: PersonAlbum: \u0060PersonAlbum\u0060 is an aggregate/entity with 3 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PersonAlbum.php"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5e3975465fc24b42091cfc3ed90869f5f858ab00a813ea90f7a4b40989bcf42"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: PhotoModerationEvent: \u0060PhotoModerationEvent\u0060 is an aggregate/entity with 3 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PhotoModerationEvent.php"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"93f4d43a679bbfab85e92eae1924d61608916b1c7f73633e087342cf3519ec9a"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: PhotoRating: \u0060PhotoRating\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PhotoRating.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"920f284a452bafbe7fc7aef7de8714ab64ace8f36d9e4547198b4f3b2d4e5437"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: PixelSize: \u0060PixelSize\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PixelSize.php"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"b3be9f295ee2c83b0107531f601d31c544dc5258bb18d37f796a2dfd0f68a265"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: PrintSize: \u0060PrintSize\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PrintSize.php"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"79ab81964495e9f3d09b96bbc08a59e66d1b003da178e43dea7d17f43ef06529"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: Purchasable: \u0060Purchasable\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Purchasable.php"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc1411c0d2d46523108d4e13e8d94238ac2b65778bc98b853198774343c3c5f7"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: PurchasablePixelSize: \u0060PurchasablePixelSize\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PurchasablePixelSize.php"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"590b1c6c80cb71b40407d1e1c4d5a2d679a7360d0974174ed20334a1ca9be127"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: PurchasablePrice: \u0060PurchasablePrice\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PurchasablePrice.php"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef31336c3cbab6951dca9e401a4582cd41c1a84260fd7abb379c1b1be94eb691"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: PurchasablePrintSize: \u0060PurchasablePrintSize\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PurchasablePrintSize.php"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cf7c03f3b8f6495f22fb3f1439f225e939687a4ecd521d1660113f4c4e6de17"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: RenamerRule: \u0060RenamerRule\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/RenamerRule.php"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"18d7c883625af55a76b09a484e6fd621a5c860fb368d4e6577084221d6dfab69"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: SizeVariant: \u0060SizeVariant\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/SizeVariant.php"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"c54d798e095c5566a652d418a1e8b8476b1bd1a387d2339008a2318f39fc8208"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: Statistics: \u0060Statistics\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Statistics.php"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"9169555b6de7b2ec4c86060c95086189b567af7587ac77575b9b88da545a4132"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: Tag: \u0060Tag\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Tag.php"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ae5a1b555c26d7d6771610031cd63332627106d2ccb4e2b21ab85f60787e98a"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: TagAlbum: \u0060TagAlbum\u0060 is an aggregate/entity with 3 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/TagAlbum.php"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bd17ffd49c292c96e530fda2a2d17e2cbbf5811860f40853593155067c8382a"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: Track: \u0060Track\u0060 is an aggregate/entity with 2 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Track.php"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"abbddfb49c0d00468f3b33a965fc9839a2e774d6722536f0cb0d2be5267735ee"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: UserGroup: \u0060UserGroup\u0060 is an aggregate/entity with 2 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/UserGroup.php"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"732a71ed1f024260c1b34f7f591f62554cd7e532001e5d7d5b036cea7d8aa6f2"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: Webhook: \u0060Webhook\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Webhook.php"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"9305a09d02d4897d43477394bc6168f351a20d0ef04e09c7b8a7a73d34b44c97"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: BucketKeyAlbum: \u0060BucketKeyAlbum\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/BucketKeyAlbum.php"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"62f029d9ffaef5b36d87b53f42f697976cda5ec3997fd1bf88e639ac359b310d"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: BucketKeyPhoto: \u0060BucketKeyPhoto\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/BucketKeyPhoto.php"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"bca864a4e6f999a2325810ea00dce59e2efc0fdb1adc8f786fad630c4099c78f"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: MovePhotos_Photo: \u0060MovePhotos_Photo\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/MovePhotos_Photo.php"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5d6d381946011b9ef34c1b925dc5e648cdb81d414d44c2e0ce811f4e38e046e"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: NestedSetForAlbums_AlbumModel: \u0060NestedSetForAlbums_AlbumModel\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/NestedSetForAlbums_AlbumModel.php"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b7f5efef9a33505c1abf56ba53115fec28314c2ec935d37be3cfa8a552a55ba"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: PhotoVideo: \u0060PhotoVideo\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/PhotoVideo.php"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"da5c6c19fe5e1ea6ec398c91d970bcf053267b153c8e353f0724de98baed7462"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: RatedPhoto: \u0060RatedPhoto\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/RatedPhoto.php"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ac66c5c1040ca5aac21a11ab293941ce2d93bfa4a29e5b2b84077cd08f5fbf3"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: RefactorAlbumModel_AlbumModel: \u0060RefactorAlbumModel_AlbumModel\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/RefactorAlbumModel_AlbumModel.php"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"cefa0e493ecb7bf155f1f5a334c21dbd623696032fe65903f999d57bdd5a1554"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: TitleSplitBaseAlbum: \u0060TitleSplitBaseAlbum\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/TitleSplitBaseAlbum.php"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"484ad93baa6739b52dd994364832fdbf5fd49aaf0c310e4dbfb524a69ab4dbde"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: TitleSplitPhoto: \u0060TitleSplitPhoto\u0060 is an aggregate/entity with 1 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/TitleSplitPhoto.php"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb0e17cf2adb997ae8dbfa24ce936aee1a9b67b054667b359b1c78fe972f7190"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: Album: \u0060Album\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Admin/Maintenance/Model/Album.php"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca6baed66af702bbe851110fa8c04b4e566e23cc84e90a033def307a3048efb7"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: PhotoResource: \u0060PhotoResource\u0060 exposes publicly writable state (id, album_id, checksum, created_at, description, is_highlighted, and 24 more)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/PhotoResource.php"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad07be6dc9f0c7be8e818c6188781f2e217f574e7dbaf0f425f56203ec83f998"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: ThumbAlbumResource: \u0060ThumbAlbumResource\u0060 exposes publicly writable state (id, title, description, thumb, is_nsfw, is_pinned, and 14 more)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Resources/Models/ThumbAlbumResource.php"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad92c4b85a7f55bd6ecc4f3012b44e3e084f8e85fbcd9be2c60e46b9484ace37"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: AlbumSizeStatistics: \u0060AlbumSizeStatistics\u0060 exposes publicly writable state (incrementing, timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/AlbumSizeStatistics.php"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"33fe42f73a7ea550f5ad97990b04b4d5f4dcd30e5405555887138fa8069d0560"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: AlbumUserThumb: \u0060AlbumUserThumb\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/AlbumUserThumb.php"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"78eac6384deacc1cbf927922d22af8cdeeb26cb30f51596b87204e527f695d57"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: BaseAlbumImpl: \u0060BaseAlbumImpl\u0060 exposes publicly writable state (incrementing)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/BaseAlbumImpl.php"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfc0a7d8dcfb3eef80979e4e5cc1c5408e017619d946563f373d371d22237139"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: Colour: \u0060Colour\u0060 exposes publicly writable state (incrementing, timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Colour.php"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"07dc59e56eb3ecf44d07f25ddfc77eac118eeb89596aaf8054e405fce6860760"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: Configs: \u0060Configs\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Configs.php"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8c372063439b8eff18139d49f9dcfd7fbbb7b3cf25ceaa11cab7de892fe0fc3"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: BaseAlbum: \u0060BaseAlbum\u0060 exposes publicly writable state (incrementing)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Extensions/BaseAlbum.php"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"9476b52bbd41e833e1c16583e2db6e52a0ee4712992ca4e20e2088e8448ff507"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: Face: \u0060Face\u0060 exposes publicly writable state (incrementing)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Face.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbdd13f2fa0be30095ffceea8636fe2dbbb47a0a2f0cff4b744eb23263a69ee2"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: FaceSuggestion: \u0060FaceSuggestion\u0060 exposes publicly writable state (timestamps, incrementing)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/FaceSuggestion.php"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"22d981e1c9e14219e485258b3538e393f23069f8e862076b65b40951e716018b"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: LandingFeaturedItem: \u0060LandingFeaturedItem\u0060 exposes publicly writable state (incrementing)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/LandingFeaturedItem.php"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c4368fcf232dd3c230abae146993b2de8591131d1c72c91b2b9f39d9c5e4e44"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: LandingLink: \u0060LandingLink\u0060 exposes publicly writable state (incrementing)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/LandingLink.php"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ddce9960828938e1e5f7e5e5bbe7543b0f7813989f8cebdf109abebdecd9002"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: OrderItem: \u0060OrderItem\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/OrderItem.php"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ce0cdd3ea3997ecccf2668d48aeca8392bbeb317b6ff9a027f58ba1cba9e6aa"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: Palette: \u0060Palette\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Palette.php"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3a1aa334f9e8c53b45928400379f5192101c24a14688a4f44f8f83971752ba9"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: Person: \u0060Person\u0060 exposes publicly writable state (incrementing)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Person.php"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"812150df83eb85657289ea8864bef71a1c4034e3c2e2ba26989c167a2f935106"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: Photo: \u0060Photo\u0060 exposes publicly writable state (incrementing)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Photo.php"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"4aafe0e644e0fd170a9a1debf01d511a5307355d66684ef2d64995ff9257e911"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: PhotoRating: \u0060PhotoRating\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PhotoRating.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2975db78086b8a53a52fdd1a4d61a7537378ae18855122e5e6d65c1a078f1cb"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: PixelSize: \u0060PixelSize\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PixelSize.php"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"070fddf2b6e2f9f538f62f4615073809cef9f734a7d92883e5ac22af8df9c2d7"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: PrintSize: \u0060PrintSize\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PrintSize.php"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"c83894e9aa0f60c5f690f847cf0c0ea78047c9191816fe0c966e7a975b7fd6c9"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: Purchasable: \u0060Purchasable\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Purchasable.php"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0c1cdecbd65d825289385cee4e19a4f77352082fd36bff9605cb3c49c9cc8c2"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: PurchasablePixelSize: \u0060PurchasablePixelSize\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PurchasablePixelSize.php"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"3986f07869ef586bb969739c4d23b60eef3e7e31f2e855553d73123198df7462"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: PurchasablePrice: \u0060PurchasablePrice\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PurchasablePrice.php"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2229034927ef0a330011c7f083cf67529243ec4ef9b8ff47f227aa438c67694"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: PurchasablePrintSize: \u0060PurchasablePrintSize\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/PurchasablePrintSize.php"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e243828a652b9738341e1e053a9142645748fd747cce222ac520907e1a63f1b"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: RenamerRule: \u0060RenamerRule\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/RenamerRule.php"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3ebebc8f8e38b6ed189e94e5681bb398d0d23a5c13a13762eda20cedf15832a"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: SizeVariant: \u0060SizeVariant\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/SizeVariant.php"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"c277cffa9970b1c250161dfd0c412ebe78dff00c84f26c58b5d3a27d06c3cd3a"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: Statistics: \u0060Statistics\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Statistics.php"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"86c2907ccf6e535c2cf893781de3b13609997dca9b1ae897c52ce3a2ef61132d"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: Tag: \u0060Tag\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Tag.php"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"29e17a2fce9fd63d91dde6383f8ef7f03b0fc338cdfb551d3ab69a45b42a9fe0"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: Webhook: \u0060Webhook\u0060 exposes publicly writable state (incrementing)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Models/Webhook.php"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc9edf5d2ccb36132d849373cafb9cc7a3181e0b311cac816c5a690b622545fb"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: BucketKeyAlbum: \u0060BucketKeyAlbum\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/BucketKeyAlbum.php"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"14a4edfb8fd74a609ce4fd00152d554823ef0b1147ba6947231b7125c4366f46"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: BucketKeyPhoto: \u0060BucketKeyPhoto\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/BucketKeyPhoto.php"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed547e74be243635a338de190291112f4aee99f202653fcbf5afbdacb6f068dd"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: RefactorAlbumModel_AlbumModel: \u0060RefactorAlbumModel_AlbumModel\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/RefactorAlbumModel_AlbumModel.php"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"6627bed9885dcb8a4603bbba68bd4e2f609233d242154f422b06c4342cb5872e"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: TitleSplitBaseAlbum: \u0060TitleSplitBaseAlbum\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/TitleSplitBaseAlbum.php"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a43eb31a8d89e733616c1566513bd18bb8f12ae39ddeaac641c8cc3928ce3a7"}},{"ruleId":"DM5","level":"warning","message":{"text":"Mutable entity: TitleSplitPhoto: \u0060TitleSplitPhoto\u0060 exposes publicly writable state (timestamps)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/TemporaryModels/TitleSplitPhoto.php"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"9833b815cd6f3a4b98c20ce23de5ecd5d372a4664df97782d82c000d0e77dbf5"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/2-how-to/configure-pagination.md documents the environment variable \u0060LYCHEE_ALBUMS_PER_PAGE\u0060, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/2-how-to/configure-pagination.md"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1634b180b2abeea76d4fee5921c3723bed9469456e468bf0b0a9bc637efeef6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/2-how-to/configure-pagination.md documents the environment variable \u0060LYCHEE_PHOTOS_PER_PAGE\u0060, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/2-how-to/configure-pagination.md"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"8103c2e89485957c5460686927eb6842b6f3c0f2ec8212cd6b81285e1079ed33"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/2-how-to/configure-pagination.md documents the environment variable \u0060LYCHEE_ALBUMS_PAGINATION_UI_MODE\u0060, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/2-how-to/configure-pagination.md"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"05e19ae2bf458eec0bed79ef00e1466ed4090db8a468673518af610701c05746"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/2-how-to/configure-pagination.md documents the environment variable \u0060LYCHEE_PHOTOS_PAGINATION_UI_MODE\u0060, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/2-how-to/configure-pagination.md"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8c63a518bd7376f76bccde33c2a96510f3ea97c15884b2e09cbe0bfb2ce6caa"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/2-how-to/customize-v8-nuxt-ui.md documents the environment variable \u0060NAMED_COLORS\u0060, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/2-how-to/customize-v8-nuxt-ui.md"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5ffcf7e1c694908b65a671cf18bcb40799b90a61b940c8904b1840c9d9a1624"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/2-how-to/deploy-worker-mode.md runs \u0060docker compose logs -f lychee_worker  # Monitor logs\u0060, but \u0060lychee_worker\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/2-how-to/deploy-worker-mode.md"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"34d2088cd88c10432c7102ff5954b6fce2bff4deadbe4234bcdf5996f6de8eaf"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/2-how-to/deploy-worker-mode.md runs \u0060docker compose exec lychee_worker pgrep -f \u0027queue:work\u0027\u0060, but \u0060queue:work\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/2-how-to/deploy-worker-mode.md"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5e8258e33c4076ec5040855fd93e172b0d9ab978c3abf3b45283b8e43c94b54"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/3-reference/coding-conventions.md names \u0060database/database.sqlite\u0060, but no file or folder \u0060database/database.sqlite\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/3-reference/coding-conventions.md"},"region":{"startLine":298}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ace3fa01f6bba37444a6df0bd6b14c1a49ec5e9a62ac1d8313b4f5d0f734954"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/3-reference/frontend-architecture.md names \u0060user-service.ts\u0060, but no file or folder \u0060user-service.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/3-reference/frontend-architecture.md"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e517023b92bb4c1d6d554b9142324c503349b872f5b31fc7e35b9cbb76cf8ff"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/3-reference/frontend-architecture.md names \u0060style/preset\u0060, but no file or folder \u0060style/preset\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/3-reference/frontend-architecture.md"},"region":{"startLine":458}}}],"partialFingerprints":{"codehealthFindingId/v1":"d373fe5513ced5c831d08b64fc8b46e55c0114a1c216577035d75cb24bf4a2a0"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/3-reference/settings_dependencies.md names \u0060Timeline\\InitResource\u0060, but no file or folder \u0060Timeline/InitResource\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/3-reference/settings_dependencies.md"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6dde038f0b49a6e6ace65fe8551cd5bc95e723297dbf8294bc8ab4848767928"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/README.md names \u0060runbook-template.md\u0060, but no file or folder \u0060runbook-template.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/README.md"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"56745ec7f0190f9d1b90f98db4c393cfe893f18777a08051ca0941c616a4a0f2"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/knowledge-map.md names \u0060AlbumListing\\AlbumChildrenController\u0060, but no file or folder \u0060AlbumListing/AlbumChildrenController\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/knowledge-map.md"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d9adef011467558d986623f454c098ea36428986795ec300d10deb1b384dcc6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/knowledge-map.md names \u0060AlbumListing\\AlbumRootController\u0060, but no file or folder \u0060AlbumListing/AlbumRootController\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/knowledge-map.md"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd49640c9b566665a068a4938f90ad291d4731ceea6d8af27bfa06ae5e9f06cc"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/knowledge-map.md names \u0060Http\\Controllers\\Traits\\ServesSizeVariantAssetTrait\u0060, but no file or folder \u0060Http/Controllers/Traits/ServesSizeVariantAssetTrait\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/knowledge-map.md"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c635b02bcbeca7bf3480aa91476f6d8e5cb82a9a47986e6a8fd0ef290a61e00"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/knowledge-map.md names \u0060Http\\Requests\\Traits\\ResolvesSizeVariantAssetTrait\u0060, but no file or folder \u0060Http/Requests/Traits/ResolvesSizeVariantAssetTrait\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/knowledge-map.md"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5d8bf5350852fcf32bfe0ffb7d5beecaf6c7776fa88f9f1b3da32b76ab198a9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/5-operations/session-quick-reference.md runs \u0060./scripts/validate-docs.sh\u0060, but \u0060scripts/validate-docs.sh\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/5-operations/session-quick-reference.md"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"131146cadfefc3a3688b8c78afd48af07d0d1ea1a402f18091880d383e86d4b6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/5-operations/verifying-releases.md names \u0060Lychee.zip.sigstore.json\u0060, but no file or folder \u0060Lychee.zip.sigstore.json\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/5-operations/verifying-releases.md"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"699cc8d699879cebfec54a00346978d828d49eddfadc2cdb4b7fcebf1adb31e0"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/5-operations/verifying-releases.md names \u0060.sigstore.json\u0060, but no file or folder \u0060.sigstore.json\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/5-operations/verifying-releases.md"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba753c3388a5132a02ec0428f29dacccd1f1d3986ebc8429080ac971bea2b095"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/6-decisions/ADR-0007-v8-admin-setup-gate-bypass.md names \u0060install/admin\u0060, but no file or folder \u0060install/admin\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/6-decisions/ADR-0007-v8-admin-setup-gate-bypass.md"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b2040b3297c1bf937857e626c656d5690b928f7cc1d599d1396bab1c1417f21"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/6-decisions/ADR-0010-album-user-thumb-cache-purge-on-revocation.md names \u0060Actions\\Album\\Delete\u0060, but no file or folder \u0060Actions/Album/Delete\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/6-decisions/ADR-0010-album-user-thumb-cache-purge-on-revocation.md"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba0f620567a1802c1eacc83f1dc407a098f63c6bbd4ba6b3d4e77b1e54fb0bf3"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/6-decisions/ADR-096-01-vite-plus-single-frontend-toolchain.md names \u0060env.d.ts\u0060, but no file or folder \u0060env.d.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/6-decisions/ADR-096-01-vite-plus-single-frontend-toolchain.md"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d237b97a30cae9de84d4d0d75174af90bee65a3d673f3894f1ba7fa869b83ae"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/6-decisions/ADR-101-01-docker-imagemagick-jxl.md names \u0060policy.xml\u0060, but no file or folder \u0060policy.xml\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/6-decisions/ADR-101-01-docker-imagemagick-jxl.md"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ee97a5aad0152ebb476ee0c7b5f1d9db210279792346394983783700f767bf8"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/plan.md names \u0060app/Http/Controllers/PhotoController.php\u0060, but no file or folder \u0060app/Http/Controllers/PhotoController.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/plan.md"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a780021748aca63d9209b170942b17e91aed21ac0193fdfdb80210a11908049"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/plan.md names \u0060resources/js/components/drawers/PhotoDetails.vue\u0060, but no file or folder \u0060resources/js/components/drawers/PhotoDetails.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/plan.md"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"f875cb38b722575c4ba271442950df5771a2f6eb78edd6f73d728c8e40b48f4b"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/plan.md"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bb256d5068f4b41ff9947eaa6d625cdf989bdc6cb11de57a0ad618444e3cbde"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/plan.md"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"95907b3e758cbd5ef2c4b2c69850ccfc12b84a8f1c4c40a594555585e1b124a5"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/plan.md names \u0060tests/Unit/Models/PhotoRatingTest.php\u0060, but no file or folder \u0060tests/Unit/Models/PhotoRatingTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/plan.md"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dc250166ceeeedfc5db236924c5bdf3e9df9ff7add9a5cd4173ea46e08f2872"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/plan.md names \u0060tests/Feature_v2/Photo/PhotoRatingTest.php\u0060, but no file or folder \u0060tests/Feature_v2/Photo/PhotoRatingTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/plan.md"},"region":{"startLine":299}}}],"partialFingerprints":{"codehealthFindingId/v1":"8761a1493b0d3855f854f2d7e5b68d144a8bc7a6242b338d5929f4f0c6653af3"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/plan.md names \u0060tests/Feature_v2/Resources/PhotoResourceTest.php\u0060, but no file or folder \u0060tests/Feature_v2/Resources/PhotoResourceTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/plan.md"},"region":{"startLine":345}}}],"partialFingerprints":{"codehealthFindingId/v1":"75aa8c46b6f64d38739b0dc87bce9d700046147aa07914e5d32c4d0b5a15e432"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/plan.md names \u0060resources/js/components/gallery/albumModule/thumbs/PhotoThumb.vue\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/thumbs/PhotoThumb.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/plan.md"},"region":{"startLine":528}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0f0156ca5655bf32a59dbc912341869d6f00b41637a928c238a5dd248ec930f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/plan.md names \u0060resources/js/components/gallery/photoModule/PhotoPanel.vue\u0060, but no file or folder \u0060resources/js/components/gallery/photoModule/PhotoPanel.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/plan.md"},"region":{"startLine":616}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f785e8edb2ad830683ca340dcaec4b98df50ffb066e1672d82e739457658a9c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/plan.md names \u0060resources/js/components/gallery/photoModule/PhotoBox.vue\u0060, but no file or folder \u0060resources/js/components/gallery/photoModule/PhotoBox.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/plan.md"},"region":{"startLine":625}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6cb8edc41711104f7e5f7634185085201a5dba25233464ddea3e22ae814b05c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/spec.md names \u0060tests/Feature_v2/Photo/PhotoRatingTest.php\u0060, but no file or folder \u0060tests/Feature_v2/Photo/PhotoRatingTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/spec.md"},"region":{"startLine":368}}}],"partialFingerprints":{"codehealthFindingId/v1":"4929cef7f6b3ded5aa077339e212ecc63ccbf09539477898d095b412fcdeb2aa"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/tasks.md names \u0060tests/Unit/Models/PhotoRatingTest.php\u0060, but no file or folder \u0060tests/Unit/Models/PhotoRatingTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/tasks.md"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"b88bec13593ec1c18086caf4fa9063a989b4b47b604d88fa38cd9392c4101ee8"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/tasks.md"},"region":{"startLine":260}}}],"partialFingerprints":{"codehealthFindingId/v1":"26a36adec11ba04d1f0f59402a05e57a118cb493ddd8e30b789727c3c1930632"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/tasks.md"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"3189f5d0a5d27202ee01f61096570e8fccab06f5fcc03fa1a9127e9f7ee21861"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/tasks.md names \u0060resources/js/components/gallery/photoModule/PhotoRatingWidget.vue\u0060, but no file or folder \u0060resources/js/components/gallery/photoModule/PhotoRatingWidget.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/tasks.md"},"region":{"startLine":326}}}],"partialFingerprints":{"codehealthFindingId/v1":"a913c075c789f0d5d828f6e7ba4ee1a1379c46dd45e785223e1b2a3ecb1fe7b4"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/tasks.md names \u0060resources/js/components/drawers/PhotoDetails.vue\u0060, but no file or folder \u0060resources/js/components/drawers/PhotoDetails.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/tasks.md"},"region":{"startLine":365}}}],"partialFingerprints":{"codehealthFindingId/v1":"37a619fa2686efa928f4659b582c6efaaddeb1f3b6c56340c14f55de98822751"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/tasks.md names \u0060resources/js/components/gallery/albumModule/thumbs/ThumbRatingOverlay.vue\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/thumbs/ThumbRatingOverlay.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/tasks.md"},"region":{"startLine":392}}}],"partialFingerprints":{"codehealthFindingId/v1":"f995a69776a19213f992478c21b533f5c956520fd690f0e8ca6a127802092087"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/tasks.md names \u0060resources/js/components/gallery/albumModule/thumbs/PhotoThumb.vue\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/thumbs/PhotoThumb.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/tasks.md"},"region":{"startLine":428}}}],"partialFingerprints":{"codehealthFindingId/v1":"35020eeb16c11b93f9f0f954aebedcac8c5944da211e8c42e85a80e6f30fe94a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/tasks.md names \u0060resources/js/components/gallery/photoModule/PhotoRatingOverlay.vue\u0060, but no file or folder \u0060resources/js/components/gallery/photoModule/PhotoRatingOverlay.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/tasks.md"},"region":{"startLine":456}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2dd9f0b9bab348855a8f24ca586160994355e8dd69272a8686e28704c815674"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/001-photo-star-rating/tasks.md names \u0060resources/js/components/gallery/photoModule/PhotoPanel.vue\u0060, but no file or folder \u0060resources/js/components/gallery/photoModule/PhotoPanel.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/001-photo-star-rating/tasks.md"},"region":{"startLine":495}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4db1e25f714f458e05984c0270060700b175c48d95aefa5d6a5f4bf39eb3515"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/plan.md runs \u0060docker compose logs -f lychee_worker\u0060, but \u0060lychee_worker\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/plan.md"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d571c1e1402f31feeab0a4a5178fa03e9fd634f3ce2ab36dfb6bfacb71afcdf"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/plan.md links to \u0060docker/scripts/entrypoint.sh\u0060, but \u0060docs/specs/4-architecture/features/002-worker-mode/docker/scripts/entrypoint.sh\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/plan.md"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"41878b2a47d6b1484fbe171a04411ff611a4b32e09053e91148a1aa0ea5bf4c2"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/plan.md documents the environment variable \u0060WORKER_PID\u0060, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/plan.md"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"18d88d296d29e7d894a9b2af7810ff122b1f072dc9de87d47438632150ea78fd"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/plan.md runs \u0060docker exec $(docker ps -q -f ancestor=lychee-test) pkill -f queue:work\u0060, but \u0060ancestor=lychee-test)\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/plan.md"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f187721676fab05ffdf997fa6f15bb4e0b5740bce95bb45d1f8f03302f924de"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/plan.md runs \u0060docker exec $(docker ps -q -f ancestor=lychee-test) pkill -f queue:work\u0060, but \u0060queue:work\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/plan.md"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"392b18973577a5858f28f95f6f6f799c16b2c0c3a9c23992a086934737dee06e"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/plan.md links to \u0060config/queue.php\u0060, but \u0060docs/specs/4-architecture/features/002-worker-mode/config/queue.php\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/plan.md"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b4e3b25a649f098fe93f2cce543cfd71b436238bb894961851e6db78e4169ca"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/plan.md documents the environment variable \u0060QUEUE_CONN\u0060, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/plan.md"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ad6713237da41b38c726322c569a50b332fd734803e91a6f1d82c88d9ab1223"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/plan.md links to \u0060docker\u0060, but \u0060docs/specs/4-architecture/features/002-worker-mode/docker\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/plan.md"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"e694870dbad55042de7c26fae70aca31f440b8b398f9f6695e8bedad608a445b"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/plan.md runs \u0060docker compose logs -f lychee_api   # Web mode\u0060, but \u0060lychee_api\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/plan.md"},"region":{"startLine":384}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f50002f7c7ecdb24ac4424f3fdcc4e790aa2460866eef2089a0cd2ddcdbfecf"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/plan.md runs \u0060npm run check  # If linter exists for docs\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/plan.md"},"region":{"startLine":487}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b7812c560696e897afe511d042151076421cb74ff6e9fdd27ac55ed5f33c1aa"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/plan.md runs \u0060./tests/docker/run-all-scenarios.sh\u0060, but \u0060tests/docker/run-all-scenarios.sh\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/plan.md"},"region":{"startLine":532}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbc9b85313aac3c2f88d349c240e208cf69427134d72df382bd7c82221809241"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/plan.md links to \u0060../../5-operations/analysis-gate-checklist.md\u0060, but \u0060docs/specs/4-architecture/5-operations/analysis-gate-checklist.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/plan.md"},"region":{"startLine":564}}}],"partialFingerprints":{"codehealthFindingId/v1":"53ccca52d471a987db7b56fdfa887a049c207f3032acbbdb98ff3b851adb56e4"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/002-worker-mode/tasks.md runs \u0060docker compose exec lychee_worker pkill -f queue:work\u0060, but \u0060queue:work\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/002-worker-mode/tasks.md"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd6cd9c5d50f22eed75dffb582a9806373f7bbb9202e91a09619766b9cc3bfac"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/plan.md links to \u0060docs/specs/5-operations/analysis-gate-checklist.md\u0060, but \u0060docs/specs/4-architecture/features/003-album-computed-fields/docs/specs/5-operations/analysis-gate-checklist.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/plan.md"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd97499b1d3b2f63ac002089300a19c505f4dc073124053a1ac3cb2308b0d5a8"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/plan.md names \u0060tests/Unit/Jobs/RecomputeAlbumStatsJobTest.php\u0060, but no file or folder \u0060tests/Unit/Jobs/RecomputeAlbumStatsJobTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/plan.md"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"8bd3c41da18374cf6982a5523bc6255ccbeb3e0d8ab2cf417be4f53acee7199e"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/plan.md names \u0060tests/Precomputing/CoverSelectionTest.php\u0060, but no file or folder \u0060tests/Precomputing/CoverSelectionTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/plan.md"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"8cd7ac3a0c80b979346aad5909dae1acecc8ed6f73b87c619a45f3666e699df5"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/plan.md names \u0060tests/Precomputing/PropagationTest.php\u0060, but no file or folder \u0060tests/Precomputing/PropagationTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/plan.md"},"region":{"startLine":237}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed882ad04ea32bb3fd347e07753becd36fff1975a94118569894789dd3b15528"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/plan.md names \u0060tests/Precomputing/EventListenerTest.php\u0060, but no file or folder \u0060tests/Precomputing/EventListenerTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/plan.md"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"48800953ce9a1d7aef6b32b590e00d4251b96cd1cc950d08e52488de68b6d03f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/plan.md names \u0060tests/Precomputing/CoverDisplayTest.php\u0060, but no file or folder \u0060tests/Precomputing/CoverDisplayTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/plan.md"},"region":{"startLine":286}}}],"partialFingerprints":{"codehealthFindingId/v1":"19754cee60e3c3134de598502ee471e40ded85af67ab3b67bf5a2bc805dc083c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/plan.md names \u0060tests/Precomputing/RecomputeAlbumStatsCommandTest.php\u0060, but no file or folder \u0060tests/Precomputing/RecomputeAlbumStatsCommandTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/plan.md"},"region":{"startLine":362}}}],"partialFingerprints":{"codehealthFindingId/v1":"8214d04cf9d6f4c09411b85676c200add07df95eb14399afef06180654dc752b"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/plan.md links to \u0060../../6-decisions/ADR-0003-album-computed-fields-precomputation.md\u0060, but \u0060docs/specs/4-architecture/6-decisions/ADR-0003-album-computed-fields-precomputation.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/plan.md"},"region":{"startLine":461}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a7b5165cc056f07c27fe4711f6d84580b2e367506c02b3d1eb256fed3a88f51"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/spec.md links to \u0060app/Models/Builders/AlbumBuilder.php\u0060, but \u0060docs/specs/4-architecture/features/003-album-computed-fields/app/Models/Builders/AlbumBuilder.php\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/spec.md"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5a77f68e98432312bc775229aeebace6d27f2eaa5e42049847d28433710b84d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/spec.md links to \u0060../../4-architecture/album-tree-structure.md\u0060, but \u0060docs/specs/4-architecture/4-architecture/album-tree-structure.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/spec.md"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"895aa5eac560381b91b68b2b583c4927ceaacd1c81d267759f82c7d269afe9a6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/spec.md links to \u0060../../6-decisions/ADR-0003-album-computed-fields-precomputation.md\u0060, but \u0060docs/specs/4-architecture/6-decisions/ADR-0003-album-computed-fields-precomputation.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/spec.md"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"babbe5251441978636e857f663a5e63e0912ed69cda594f5bbf8ed20715134bf"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/spec.md links to \u0060app/Relations/HasAlbumThumb.php\u0060, but \u0060docs/specs/4-architecture/features/003-album-computed-fields/app/Relations/HasAlbumThumb.php\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/spec.md"},"region":{"startLine":272}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8f6086e875d609004f8b9a720a8e668dd329550ff8e53bfdb145a2919ed4140"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/tasks.md names \u0060tests/Unit/Jobs/RecomputeAlbumStatsJobTest.php\u0060, but no file or folder \u0060tests/Unit/Jobs/RecomputeAlbumStatsJobTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/tasks.md"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fd25a49230a07f242500e6f97a2cdb42aa4f83e71b6ea8a75cfc38fbb684614"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/tasks.md names \u0060tests/Precomputing/RecomputeAlbumStatsJobTest.php\u0060, but no file or folder \u0060tests/Precomputing/RecomputeAlbumStatsJobTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/tasks.md"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a7c3fa4a6b4424d0ff3b49b8a313425cac786ea9bfc4b634bd8fedfc2d41b05"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/tasks.md names \u0060tests/Feature/Console/RecomputeAlbumStatsCommandTest.php\u0060, but no file or folder \u0060tests/Feature/Console/RecomputeAlbumStatsCommandTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/tasks.md"},"region":{"startLine":457}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0668b21d643e7f0bec92cc3c9c8322877ca8eba3a92d90afca161330bf5369a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/003-album-computed-fields/tasks.md names \u0060tests/Feature/Console/BackfillAlbumFieldsCommandTest.php\u0060, but no file or folder \u0060tests/Feature/Console/BackfillAlbumFieldsCommandTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/003-album-computed-fields/tasks.md"},"region":{"startLine":465}}}],"partialFingerprints":{"codehealthFindingId/v1":"82cf1a38269437a03963f9ce0e29575754d1059daa81ac8109e1835d662b9b28"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/004-album-size-statistics/plan.md names \u0060docs/specs/4-architecture/features/004-album-size-statistics/performance-benchmarks.md\u0060, but no file or folder \u0060docs/specs/4-architecture/features/004-album-size-statistics/performance-benchmarks.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/004-album-size-statistics/plan.md"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"9fe1fd81ce596abee3ff9f0c4a75966f0ae0b1951cfe2261bc09c51985358b88"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/004-album-size-statistics/plan.md names \u0060resources/js/components/admin/Maintenance.vue\u0060, but no file or folder \u0060resources/js/components/admin/Maintenance.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/004-album-size-statistics/plan.md"},"region":{"startLine":294}}}],"partialFingerprints":{"codehealthFindingId/v1":"70648c99afa18d5bba6b8d1b28c8a464de92cacbe9aee96159b632dbf6689435"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/004-album-size-statistics/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/004-album-size-statistics/plan.md"},"region":{"startLine":307}}}],"partialFingerprints":{"codehealthFindingId/v1":"5224384440111cf0d1c0fd4beef66bf5d09211a06fc48cec4b06497731ed20dc"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/004-album-size-statistics/spec.md links to \u0060app/Actions/Statistics/Spaces.php\u0060, but \u0060docs/specs/4-architecture/features/004-album-size-statistics/app/Actions/Statistics/Spaces.php\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/004-album-size-statistics/spec.md"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"4102885e449ee3a57379fbce128ff7fc653a720ee9aecaee147d11223fe6b487"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/004-album-size-statistics/spec.md links to \u0060../../6-decisions/ADR-0004-album-size-statistics-precomputation.md\u0060, but \u0060docs/specs/4-architecture/6-decisions/ADR-0004-album-size-statistics-precomputation.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/004-album-size-statistics/spec.md"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"5afc59081694b2483da7d04189ad1e9583de2efde67d95680558670744b7508d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/004-album-size-statistics/spec.md links to \u0060app/Enum/SizeVariantType.php\u0060, but \u0060docs/specs/4-architecture/features/004-album-size-statistics/app/Enum/SizeVariantType.php\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/004-album-size-statistics/spec.md"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"1749da4dc3e23a4746b59cacff4b7db734e7f654c9638236cae8f5d636808c8c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/004-album-size-statistics/tasks.md names \u0060resources/js/views/Maintenance.vue\u0060, but no file or folder \u0060resources/js/views/Maintenance.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/004-album-size-statistics/tasks.md"},"region":{"startLine":290}}}],"partialFingerprints":{"codehealthFindingId/v1":"23d83a02adc5cc09854552ba99620295ac125bffff908e421b145364a2aec2a1"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/004-album-size-statistics/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/004-album-size-statistics/tasks.md"},"region":{"startLine":320}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc20bc6e7eb78cfa997ec421a2f96d81c3909c108b5ac5eb4f1a2c3ca69fa9bc"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/004-album-size-statistics/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/004-album-size-statistics/tasks.md"},"region":{"startLine":321}}}],"partialFingerprints":{"codehealthFindingId/v1":"635f8193de5bec0408f6162f98452609d72c3f6c658e66bb94e43d7ac856daff"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/004-album-size-statistics/tasks.md names \u0060docs/specs/4-architecture/features/004-album-size-statistics/performance-benchmarks.md\u0060, but no file or folder \u0060docs/specs/4-architecture/features/004-album-size-statistics/performance-benchmarks.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/004-album-size-statistics/tasks.md"},"region":{"startLine":390}}}],"partialFingerprints":{"codehealthFindingId/v1":"0dce56a6ba7641741fdf9d047c2c39cf5d584e4b4ccf000274e094ced9d996d1"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/005-album-list-view/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/005-album-list-view/plan.md"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"04dcb3b35262033a1a809d5fd9bbcd1978a70e7afb1a57523a6fb4dede89d855"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/005-album-list-view/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/005-album-list-view/plan.md"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"99e17bae712511a77bc8db4a8a51c171217123abcb4698b06bc6f84be7f68ed5"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/005-album-list-view/plan.md links to \u0060IMPLEMENTATION-SNIPPETS.md#2-initconfigphp\u0060, but \u0060docs/specs/4-architecture/features/005-album-list-view/IMPLEMENTATION-SNIPPETS.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/005-album-list-view/plan.md"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd588c3e1ae68be9b12e4b4f69d122fb29663a4d1328c8db69787a7f7729693d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/005-album-list-view/plan.md names \u0060resources/js/components/headers/AlbumsHeader.vue\u0060, but no file or folder \u0060resources/js/components/headers/AlbumsHeader.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/005-album-list-view/plan.md"},"region":{"startLine":433}}}],"partialFingerprints":{"codehealthFindingId/v1":"a62dc8af7ed730b171c9199e5c79e3a0dd7550e284e0da877880183f834ec707"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/005-album-list-view/spec.md links to \u0060docs/specs/3-reference/coding-conventions.md\u0060, but \u0060docs/specs/4-architecture/features/005-album-list-view/docs/specs/3-reference/coding-conventions.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/005-album-list-view/spec.md"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"bde6ace361b7e87519131317223267e504c9b3b057739eb1dd260de34a6df84a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/005-album-list-view/spec.md links to \u0060docs/specs/4-architecture/roadmap.md\u0060, but \u0060docs/specs/4-architecture/features/005-album-list-view/docs/specs/4-architecture/roadmap.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/005-album-list-view/spec.md"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e2ffa50b392e5907b867be16ab58b7183b7f66015abe4dbf5aa24846faa4ce0"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/005-album-list-view/spec.md links to \u0060docs/specs/4-architecture/knowledge-map.md\u0060, but \u0060docs/specs/4-architecture/features/005-album-list-view/docs/specs/4-architecture/knowledge-map.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/005-album-list-view/spec.md"},"region":{"startLine":278}}}],"partialFingerprints":{"codehealthFindingId/v1":"ceedad2a32287cb2873934850aadad43fd343e70a42963da09855433e6c9a6d0"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/005-album-list-view/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/005-album-list-view/tasks.md"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"e75584ca635063173180ce1b5d5b13c16d59301b4480fc6460be24b194c62aed"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/005-album-list-view/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/005-album-list-view/tasks.md"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e05510ba9a3930b51594af19e34a50118ea390d2945a367f35817028fda6fb3"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/006-photo-rating-filter/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/006-photo-rating-filter/plan.md"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ff212707f1469da81e5c09324dd8530c0b848fc4357071f03f57e4364774b30"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/006-photo-rating-filter/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/006-photo-rating-filter/plan.md"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3dd205335edbfd004e75ee6fcaa513dc2a7380902ab6b5868267d20ac117c4f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/006-photo-rating-filter/plan.md links to \u0060docs/specs/4-architecture/knowledge-map.md\u0060, but \u0060docs/specs/4-architecture/features/006-photo-rating-filter/docs/specs/4-architecture/knowledge-map.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/006-photo-rating-filter/plan.md"},"region":{"startLine":478}}}],"partialFingerprints":{"codehealthFindingId/v1":"529f22100cee972941afc0716e711609d6f704221b54bd29c8407f19b801bf54"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/006-photo-rating-filter/spec.md links to \u0060docs/specs/3-reference/coding-conventions.md\u0060, but \u0060docs/specs/4-architecture/features/006-photo-rating-filter/docs/specs/3-reference/coding-conventions.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/006-photo-rating-filter/spec.md"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"086cef5e7dd4e6da63e10bde62d95fc35b119cdfe671aa909de1b07a94bab001"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/006-photo-rating-filter/spec.md links to \u0060docs/specs/4-architecture/roadmap.md\u0060, but \u0060docs/specs/4-architecture/features/006-photo-rating-filter/docs/specs/4-architecture/roadmap.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/006-photo-rating-filter/spec.md"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"23cfbca70b143975e7962bc501a708e99ddcaa11bfc0cf1454ed6398e9ec1491"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/006-photo-rating-filter/spec.md links to \u0060docs/specs/4-architecture/knowledge-map.md\u0060, but \u0060docs/specs/4-architecture/features/006-photo-rating-filter/docs/specs/4-architecture/knowledge-map.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/006-photo-rating-filter/spec.md"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"207cea6a610d371785470b31505d4d419cb56d84ca8f3709ca84c3502230e710"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/006-photo-rating-filter/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/006-photo-rating-filter/tasks.md"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"35c5b95aa31d9cab0f26229fe13af63fe8254156d121af95b04e3c86909238db"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/007-pagination/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/007-pagination/plan.md"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0c9e7fd72ac32492b878bdd4621ebf786ed0d45e51b0731f6f8a6b8b334dd48"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/007-pagination/plan.md runs \u0060npm test services/album-service.test.ts\u0060, but no package.json declares a \u0060test\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/007-pagination/plan.md"},"region":{"startLine":302}}}],"partialFingerprints":{"codehealthFindingId/v1":"bec53405923a0e90bae19f6f77ffda16d504a375268f466252a14526a121f5e9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/007-pagination/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/007-pagination/plan.md"},"region":{"startLine":562}}}],"partialFingerprints":{"codehealthFindingId/v1":"1dacca23f0aadbf815e6631afb8a60f07ba775176c5219e36834e02bf93b4564"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/007-pagination/spec.md links to \u0060app/SmartAlbums/BaseSmartAlbum.php#L138-L149\u0060, but \u0060docs/specs/4-architecture/features/007-pagination/app/SmartAlbums/BaseSmartAlbum.php\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/007-pagination/spec.md"},"region":{"startLine":346}}}],"partialFingerprints":{"codehealthFindingId/v1":"352a8889e8ab7ad5c8a9c4a3bf829eee74e19deb9742c4cd69a00c2c71ed8862"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/007-pagination/spec.md links to \u0060app/Models/Extensions/SortingDecorator.php#L203-L247\u0060, but \u0060docs/specs/4-architecture/features/007-pagination/app/Models/Extensions/SortingDecorator.php\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/007-pagination/spec.md"},"region":{"startLine":363}}}],"partialFingerprints":{"codehealthFindingId/v1":"47c8907f8c224ab66427a247f294ab370bdcf2b960b86b4c178374223d41ad0f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/007-pagination/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/007-pagination/tasks.md"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1d197867ab0037c25a6ef9fb946c5eb8ba994bdd995ea80f887a0967838d2e2"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/007-pagination/tasks.md runs \u0060npm test services/album-service.test.ts\u0060, but no package.json declares a \u0060test\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/007-pagination/tasks.md"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c54dc7a86c491e27775239f842593be61983e7e9557ce2e447d875462dc4f06"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/007-pagination/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/007-pagination/tasks.md"},"region":{"startLine":258}}}],"partialFingerprints":{"codehealthFindingId/v1":"6749755e8bd0852f03bb6a7b99ed36008b665f8482b1b62ad21f69c9c998b48f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/008-shared-albums-visibility/plan.md names \u0060resources/js/components/gallery/\u0060, but no file or folder \u0060resources/js/components/gallery\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/008-shared-albums-visibility/plan.md"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"8eb860e5f4934db527e86cce8d3833332efef5f173856bd4a63f5b225fbef14a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/008-shared-albums-visibility/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/008-shared-albums-visibility/plan.md"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"462f3538d67563fa9a4ef6f352f77f55c540cd4ce7199836ed94318f8987b812"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/008-shared-albums-visibility/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/008-shared-albums-visibility/plan.md"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd4d187793d2f66c8f2aa74298f5a07b1b0336b2f1c53121a75d90e63223b1f5"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/008-shared-albums-visibility/spec.md links to \u0060../../../../app/Actions/Albums/Top.php\u0060, but \u0060docs/app/Actions/Albums/Top.php\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/008-shared-albums-visibility/spec.md"},"region":{"startLine":368}}}],"partialFingerprints":{"codehealthFindingId/v1":"18a2989208d8ecf5886e54217dabf8a5cbac928b7437f491fba889a0bdb718ca"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/008-shared-albums-visibility/spec.md links to \u0060../../../../app/Http/Resources/GalleryConfigs/RootConfig.php\u0060, but \u0060docs/app/Http/Resources/GalleryConfigs/RootConfig.php\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/008-shared-albums-visibility/spec.md"},"region":{"startLine":384}}}],"partialFingerprints":{"codehealthFindingId/v1":"52eed8e5e7dfab7b5b676bbeda77a4786d450925ba57def463daa06c1fde1bab"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/008-shared-albums-visibility/spec.md links to \u0060../../../../app/Models/User.php\u0060, but \u0060docs/app/Models/User.php\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/008-shared-albums-visibility/spec.md"},"region":{"startLine":387}}}],"partialFingerprints":{"codehealthFindingId/v1":"c371ce12003706ccdb2ca96069a94ae1c3dd28f4b8465e29300141ff88e16641"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/008-shared-albums-visibility/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/008-shared-albums-visibility/tasks.md"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f282f1c172e710f5eaf219a614093e8c7d9fd08a7024162703d7a8caf920021"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/008-shared-albums-visibility/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/008-shared-albums-visibility/tasks.md"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1d55f622588a776e18555fc5149f0643a9b187eab0067bc2560601563ff64d6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/009-rating-ordering/spec.md names \u0060tests/Feature_v2/SmartAlbum/RatingSmartAlbumsTest.php\u0060, but no file or folder \u0060tests/Feature_v2/SmartAlbum/RatingSmartAlbumsTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/009-rating-ordering/spec.md"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"2be3ef0aa3acb8143dc6293837ecc1877f946aa1d6a56a8df4741f58c410afcf"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/010-ldap-support/plan.md names \u0060tests/Fixtures/ldap-users.php\u0060, but no file or folder \u0060tests/Fixtures/ldap-users.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/010-ldap-support/plan.md"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"750faadec1172c25d35702b960ac693ed45fd5b372bb1d8df793d765dbd7f957"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/010-ldap-support/plan.md names \u0060tests/Fixtures/ldap-groups.php\u0060, but no file or folder \u0060tests/Fixtures/ldap-groups.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/010-ldap-support/plan.md"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"b3f947132006c7ce4de33d9e10c6c9bd1bef3636145ace24ccb4bbfd7b7c51c9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/010-ldap-support/plan.md links to \u0060../../5-operations/analysis-gate-checklist.md\u0060, but \u0060docs/specs/4-architecture/5-operations/analysis-gate-checklist.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/010-ldap-support/plan.md"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"6377c15cc931008a3000382aa32cf9283dae08d606df909257e10d51465c9347"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/010-ldap-support/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/010-ldap-support/plan.md"},"region":{"startLine":399}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcd8a9bfde7addb07f3b3dc2eda2683ff2e50e45376b8e582c1dff265c930ef3"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/010-ldap-support/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/010-ldap-support/plan.md"},"region":{"startLine":399}}}],"partialFingerprints":{"codehealthFindingId/v1":"0edc81942d6e7958a09f5a3ccea9161aa1ae6df5d850582de15da24addecd87a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/010-ldap-support/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/010-ldap-support/tasks.md"},"region":{"startLine":475}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a485b8e74d34cc37f5f20e82a62d132c3a30feb0bcc56738e567e86ba0986f8"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/010-ldap-support/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/010-ldap-support/tasks.md"},"region":{"startLine":512}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f2457b9fdd4d9906042ea04082cca2a96e95557043ce7a03bb5853dadc0a0a3"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names TypeScript 5, but the manifest declares \u0060typescript\u0060 ^6.0.3. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c13d7b3258d8947b58e568e8570a4d92f237a2cffa20eb385f53337aa4cbef6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060app/Http/Middleware/EmbedCors.php\u0060, but no file or folder \u0060app/Http/Middleware/EmbedCors.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":276}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9644542cbc93562d0d124722ef11d3af95a4fbbf04a250ca7198483b1914ad4"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060resources/js/embed/LycheeEmbed.ts\u0060, but no file or folder \u0060resources/js/embed/LycheeEmbed.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":560}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3a7311d1a431a0e2e19a400f86ec933fed67b0afb91704c3f3bfdb8aef1a7ba"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060resources/js/embed/index.ts\u0060, but no file or folder \u0060resources/js/embed/index.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":705}}}],"partialFingerprints":{"codehealthFindingId/v1":"2970ecfab196d7fb522f00002e59bd363ec013bd53816decfd33a6ce111efe7e"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060resources/js/embed/utils/responsive.ts\u0060, but no file or folder \u0060resources/js/embed/utils/responsive.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":729}}}],"partialFingerprints":{"codehealthFindingId/v1":"0332db900c867e3e9796bdbe75c736ac5b41e9832faf3b51e744ced5fc6ae69f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060resources/js/embed/layouts/SquareLayout.ts\u0060, but no file or folder \u0060resources/js/embed/layouts/SquareLayout.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":794}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b9cff3f12bbedae45701ee3ff631c25692d86a8ec05a8d87d5e2880b096eefb"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060resources/js/embed/layouts/JustifiedLayout.ts\u0060, but no file or folder \u0060resources/js/embed/layouts/JustifiedLayout.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":849}}}],"partialFingerprints":{"codehealthFindingId/v1":"6eba3da20a6d5cfded57c08533f87888773205c5a99d44ea0e08e979a4eee1f6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060resources/js/embed/layouts/MasonryLayout.ts\u0060, but no file or folder \u0060resources/js/embed/layouts/MasonryLayout.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":892}}}],"partialFingerprints":{"codehealthFindingId/v1":"0431e097c64d35304f0a46cd991da5478cd3e2992034b222d4f2b067d40a12bf"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060resources/js/embed/layouts/GridLayout.ts\u0060, but no file or folder \u0060resources/js/embed/layouts/GridLayout.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":961}}}],"partialFingerprints":{"codehealthFindingId/v1":"f25d7525101db46457705cada90ea9292d82a943704da0c7590f9b59c1d5347d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060resources/js/embed/layouts/FilmstripLayout.ts\u0060, but no file or folder \u0060resources/js/embed/layouts/FilmstripLayout.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1021}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb162c391079a7e66b8e66ff6dc2ec98f509d845aa03b0cdea9f3cae6df9cbf7"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060resources/js/components/modals/EmbedCodeModal.vue\u0060, but no file or folder \u0060resources/js/components/modals/EmbedCodeModal.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1279}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d3549411414c852518f6d82b10f163815ba8fe4c730883c0a540ade109cd8d4"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060resources/js/views/gallery-panels/Album.vue\u0060, but no file or folder \u0060resources/js/views/gallery-panels/Album.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1607}}}],"partialFingerprints":{"codehealthFindingId/v1":"a448e1737591e0149b67c202de6208b400fc338f37678ceccd4ee35514c9cb43"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md runs \u0060npm run dev:embed\u0060, but no package.json declares a \u0060dev:embed\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1658}}}],"partialFingerprints":{"codehealthFindingId/v1":"994191087f8305541a197611418fdb9dce7dcd27482d790a4bbb455124a87ecd"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md runs \u0060npm run watch:embed\u0060, but no package.json declares a \u0060watch:embed\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1661}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a08e8685fdc57f8f684ab6118ff801cb0ad952195965d00537fed2cd3e57eae"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060tests/js/embed/\u0060, but no file or folder \u0060tests/js/embed\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1717}}}],"partialFingerprints":{"codehealthFindingId/v1":"3037ff12b250cc49075080bfa8a7ded36b56a3740eb276b067621bd9d6d20ef5"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060responsive.test.ts\u0060, but no file or folder \u0060responsive.test.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1720}}}],"partialFingerprints":{"codehealthFindingId/v1":"36e78e408e08c68d551f6df73ec5203bf19655678a0fe931c9fccf2750c72c7e"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060SquareLayout.test.ts\u0060, but no file or folder \u0060SquareLayout.test.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1721}}}],"partialFingerprints":{"codehealthFindingId/v1":"4089d07451b7e5e21c99538c85234105d1fff93522338e8021020df6d9247f7a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060JustifiedLayout.test.ts\u0060, but no file or folder \u0060JustifiedLayout.test.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1722}}}],"partialFingerprints":{"codehealthFindingId/v1":"569bbbee2c7cb9d506fde0012560068fb3534d62208688e108609e28adeab273"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060MasonryLayout.test.ts\u0060, but no file or folder \u0060MasonryLayout.test.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1723}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c8d6caaabea7ab8604b5aebe619c6f725c47d0f7fe1b8ff0337ac0d8d64f3f9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060GridLayout.test.ts\u0060, but no file or folder \u0060GridLayout.test.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1724}}}],"partialFingerprints":{"codehealthFindingId/v1":"461e1a34813e504e54a659d2785a7b156a3b89ae78bf0ad3626391444899e2d0"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060FilmstripLayout.test.ts\u0060, but no file or folder \u0060FilmstripLayout.test.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1725}}}],"partialFingerprints":{"codehealthFindingId/v1":"abf7c1030af9607cac4fe981d0ed0bbca13dc78f432d3dcea9093fc509a4a2a2"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060Lightbox.test.ts\u0060, but no file or folder \u0060Lightbox.test.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1726}}}],"partialFingerprints":{"codehealthFindingId/v1":"37638e6e1ed133aa4d2da2f09cfdef5e6f4589a3c6b64104f55db4219140d878"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060ImageLoader.test.ts\u0060, but no file or folder \u0060ImageLoader.test.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1727}}}],"partialFingerprints":{"codehealthFindingId/v1":"c31f68b7fd96c43969d287dad486b489844e27c69afc56b3e91ab3af95645492"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060tests/Feature/Embed/\u0060, but no file or folder \u0060tests/Feature/Embed\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1753}}}],"partialFingerprints":{"codehealthFindingId/v1":"20c2d0e0666ccfd4de4e02f4f6918c496e81f54d8dd88a1b3f8cb6fc2253bd5a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md names \u0060resources/js/embed/api/client.ts\u0060, but no file or folder \u0060resources/js/embed/api/client.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/IMPLEMENTATION.md"},"region":{"startLine":1877}}}],"partialFingerprints":{"codehealthFindingId/v1":"b705c373c3f80db897684f7c01f67e5ba1c0b05a72c2e0d68e54b690b03e6afe"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/README.md names TypeScript 5, but the manifest declares \u0060typescript\u0060 ^6.0.3. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/README.md"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"383f72797c0cf779bf839de0f013abcbbca944a2f152df8b3d1205a9ee336386"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/README.md names \u0060resources/js/components/modals/EmbedCodeModal.vue\u0060, but no file or folder \u0060resources/js/components/modals/EmbedCodeModal.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/README.md"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"32308f6a3ae48785dda9827d1aead196d159af6f84696e13c82c62cd4f12915c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/README.md names \u0060resources/js/views/gallery-panels/Album.vue\u0060, but no file or folder \u0060resources/js/views/gallery-panels/Album.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/README.md"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"3224310fb40392143ac0875e8d9c9c17f204a5b86f3150a4781e3dbbd0e90fdd"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/README.md runs \u0060npm run test:embed\u0060, but no package.json declares a \u0060test:embed\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/README.md"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a92c15388a7575e41a9faac218671c65fa7925581417e76b4f4de3100f4fb29"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/README.md names \u0060resources/js/components/gallery/albumModule/thumbs/\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/thumbs\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/README.md"},"region":{"startLine":269}}}],"partialFingerprints":{"codehealthFindingId/v1":"50744a2ea41b791f1627a94cb6a9e4e74e5962c818c5cf7530dedabbd2a33aa6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/012-embeds/open-questions.md links to \u0060spec.md\u0060, but \u0060docs/specs/4-architecture/features/012-embeds/spec.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/012-embeds/open-questions.md"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2742984d8667cef5b1e3a33d94702b8837d946f489831c2ec4c115f752b79e5"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/013-starred-to-highlighted/tasks.md names \u0060app/Http/Requests/Photo/SetPhotosStarredRequest.php\u0060, but no file or folder \u0060app/Http/Requests/Photo/SetPhotosStarredRequest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/013-starred-to-highlighted/tasks.md"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"23c10c7985851efc9f0c1c5ad568f862502831f86dcdff1f7df060fcb6571600"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/013-starred-to-highlighted/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/013-starred-to-highlighted/tasks.md"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9059a677c125e84235ed082fa2c83849f07f1db28a793c494fc6bdb480026df"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/013-starred-to-highlighted/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/013-starred-to-highlighted/tasks.md"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"7df96627825209f0b9a8a442263e8a8b1dafd8c6ed89e5dae392ea1db0e0cf28"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/plan.md"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"f10f3761ab74566c77c53c7defe7117cc5d3f2aa4bd5216b3bc958bc2f26a722"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/plan.md runs \u0060npm run test\u0060, but no package.json declares a \u0060test\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/plan.md"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"493cf654a0690260a2fce67e0070f90fea0c790ced66c2d5a6ff7b638e278996"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/plan.md names \u0060resources/js/components/gallery/albumModule/PhotoThumbPanelControl.vue\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/PhotoThumbPanelControl.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/plan.md"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"21d7ca14a6b618a284d021f45fbde7512d7eb09da63c4272c0f79b99f13dc785"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/plan.md names \u0060resources/js/components/gallery/albumModule/PhotoThumbPanelList.vue\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/PhotoThumbPanelList.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/plan.md"},"region":{"startLine":258}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9e861b300283545b1a2206e623c70ea462e288955e8600fbf7c8dd71a2ff192"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/spec.md links to \u0060docs/specs/4-architecture/roadmap.md\u0060, but \u0060docs/specs/4-architecture/features/014-photo-list-view/docs/specs/4-architecture/roadmap.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/spec.md"},"region":{"startLine":289}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9d02a85adceec51915049aaf7ce66f55e409419af99e7f7a1ac30973f0ee6e6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/spec.md links to \u0060docs/specs/4-architecture/knowledge-map.md\u0060, but \u0060docs/specs/4-architecture/features/014-photo-list-view/docs/specs/4-architecture/knowledge-map.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/spec.md"},"region":{"startLine":290}}}],"partialFingerprints":{"codehealthFindingId/v1":"94786e992ab532e8764f957af9c77a544630f4f249a10d0ce3c46df736da405e"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/tasks.md"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1da6dc162229c10dd15c399dc02297f4ba99074ba0b3449d52bebb85f81036a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/tasks.md names \u0060resources/js/components/gallery/albumModule/PhotoThumbPanelControl.vue\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/PhotoThumbPanelControl.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/tasks.md"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4f53185b15c6a8310b14a6e5a3cbfd7bab451b54fa555ca67a46cbd46ce7703"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/tasks.md names \u0060resources/js/components/gallery/albumModule/PhotoListItem.vue\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/PhotoListItem.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/tasks.md"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d256e651fc7bf4940fb9de3c199717902793ebca301f622a0a9f7270ac0e4bc"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/tasks.md names \u0060resources/js/components/gallery/albumModule/PhotoListView.vue\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/PhotoListView.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/tasks.md"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0afb42a225451228cc2da49fdaba755ff1f80765c6102c2ffbbcfae16202270"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/tasks.md names \u0060resources/js/components/gallery/albumModule/PhotoThumbPanelList.vue\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/PhotoThumbPanelList.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/tasks.md"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"87df576924cf3cb63564f634a9c4d104e53a7689cb7454da788dfe01f4e6d617"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/tasks.md names \u0060resources/js/components/gallery/albumModule/__tests__/fixtures/photos-list-view.json\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/__tests__/fixtures/photos-list-view.json\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/tasks.md"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"f49001adbd3559fdeb930b0a2ee00cb7ae24a142c96591e957f67f828909b415"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/tasks.md names \u0060resources/js/components/gallery/albumModule/__tests__/PhotoListItem.spec.ts\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/__tests__/PhotoListItem.spec.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/tasks.md"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd70b0f7cc693dd04adaf3e1280862ffce2985304ebc71667ebbd1da2cb28a59"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/tasks.md runs \u0060npm run test -- PhotoListItem\u0060, but no package.json declares a \u0060test\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/tasks.md"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"865cd30e0f23cbc6487f2174f7936f24fa9036fcde293a6602999a6dd791e303"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/tasks.md names \u0060resources/js/components/gallery/albumModule/__tests__/PhotoListView.spec.ts\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/__tests__/PhotoListView.spec.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/tasks.md"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a2121f3afb541f7f97e948cc7eb00863742a69fed88c478777bc774d1b68d44"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/tasks.md names \u0060resources/js/components/gallery/albumModule/__tests__/PhotoThumbPanelList.spec.ts\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/__tests__/PhotoThumbPanelList.spec.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/tasks.md"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2e9933c2fa691e703502e866358484cd8d375456bfda22508519d6ac242f079"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/014-photo-list-view/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/014-photo-list-view/tasks.md"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0b317f53b27baa4187c54382deefa190f5111808f8b0c8a55ee6401bfa81ffa"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/015-upload-watermark-toggle/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/015-upload-watermark-toggle/plan.md"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ecb8349de4ae87e13e27357ff229e3781bd947c9af9437889eaff76f0442915"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/015-upload-watermark-toggle/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/015-upload-watermark-toggle/plan.md"},"region":{"startLine":218}}}],"partialFingerprints":{"codehealthFindingId/v1":"fee101a4bae7155934cde6f2c94ce854790f18bb03ddd1ac25db9a1d9e03361d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/015-upload-watermark-toggle/spec.md names \u0060resources/js/components/modals/UploadPanel.vue\u0060, but no file or folder \u0060resources/js/components/modals/UploadPanel.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/015-upload-watermark-toggle/spec.md"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe97a99b19574f21387e02bf056253f313144dd0dda161ece12500a1b9e2e2fb"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/015-upload-watermark-toggle/spec.md names \u0060resources/js/components/forms/upload/UploadingLine.vue\u0060, but no file or folder \u0060resources/js/components/forms/upload/UploadingLine.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/015-upload-watermark-toggle/spec.md"},"region":{"startLine":294}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d16209fc7863c1771441a435741d6a8465ecdeb39351e8fd03b081893977e3b"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/015-upload-watermark-toggle/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/015-upload-watermark-toggle/tasks.md"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e98c5aeafdeccfc60c6ab9304ea895b0da2c9425c763c3c925bd6c28ada14d9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/015-upload-watermark-toggle/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/015-upload-watermark-toggle/tasks.md"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0b65d36f9a33ca0f4740f95b7c5289a4d3d71dfecd66370283f49231710e8cc"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/016-bulk-license-edit/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/016-bulk-license-edit/plan.md"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"35d1fba2fcd76faa4eada8acf61644610195fab4b50705ed0357a0c500435f09"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/016-bulk-license-edit/plan.md names \u0060routes/api.php\u0060, but no file or folder \u0060routes/api.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/016-bulk-license-edit/plan.md"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d92a3640742388cee03691c143fe8a327b31d999025f94afa1c68ecdf50c2af"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/016-bulk-license-edit/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/016-bulk-license-edit/plan.md"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"c43faf09048ec585d24bd29d63272e9789bfedac8d88e1365a54a16a04a19a39"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/016-bulk-license-edit/plan.md names \u0060resources/js/components/\u0060, but no file or folder \u0060resources/js/components\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/016-bulk-license-edit/plan.md"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"29fa8e8e5f37df03195ec12d640a3c9071b94114926633cbbf0d5cf560adc732"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/016-bulk-license-edit/spec.md names \u0060resources/js/components/forms/photo/PhotoTagDialog.vue\u0060, but no file or folder \u0060resources/js/components/forms/photo/PhotoTagDialog.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/016-bulk-license-edit/spec.md"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c68dcd7311bfaab4da625ad0c99cf920ef4b75423bbc33f45b67b0aefcd06dc"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/016-bulk-license-edit/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/016-bulk-license-edit/tasks.md"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed1e6ac58e360ffb7aa3f495b7fc913b3fe4bea87618e6d1e3b70d3fbbc06a72"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/016-bulk-license-edit/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/016-bulk-license-edit/tasks.md"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0858520e812b1b58dc82616fadbd30f168e913bb21009c6f3610c8faba54f2f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/016-bulk-license-edit/tasks.md names \u0060resources/js/components/forms/photo/PhotoLicenseDialog.vue\u0060, but no file or folder \u0060resources/js/components/forms/photo/PhotoLicenseDialog.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/016-bulk-license-edit/tasks.md"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"49e0d6bddef7defef361826253d917ec26fdf06cdf325dac687cce0f37a50670"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/017-apply-renamer-rules/plan.md names \u0060resources/js/components/gallery/albumModule/AlbumHero.vue\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/AlbumHero.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/017-apply-renamer-rules/plan.md"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d37e4ed8c16d9ad5ecc0eccf0c133db9b918c6ebb1b0b5ca51e999b68c9dd4e"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/017-apply-renamer-rules/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/017-apply-renamer-rules/plan.md"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8742261b72c24ead32d9a8cb961a8ec1f729b8ee596ee7e019b8830a73b435c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/017-apply-renamer-rules/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/017-apply-renamer-rules/plan.md"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1c7ba81b9754be0c002b209d301e87850be12d6bceccffaf9e506a16c965d54"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/017-apply-renamer-rules/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/017-apply-renamer-rules/tasks.md"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"917403ded196a0cc870021bbb095bf4176e551a318933d2421900c18e15cd281"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/017-apply-renamer-rules/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/017-apply-renamer-rules/tasks.md"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab52f192190d653d5664c4ca76d3ec7256f15d21b423fd132db848841e43832f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/018-photo-albums-sidebar/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/018-photo-albums-sidebar/plan.md"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"267e998957420cccfdbb584ac89a4d984b228e5d2351af1fa277487d3f77b2c2"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/018-photo-albums-sidebar/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/018-photo-albums-sidebar/plan.md"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca1423ba42e8f8497a75855d86c07cd40296dc5fa616c3a564c69fcdf920836a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/018-photo-albums-sidebar/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/018-photo-albums-sidebar/tasks.md"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"01ad18b010cda21f7e6adfb9c689cc48751ba80f758507bb123acfe896a64131"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/018-photo-albums-sidebar/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/018-photo-albums-sidebar/tasks.md"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"c16a2979d8b3420fce8b9ac44fb6bee2d0774e7e2554a97252227a3a85297e1b"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/019-friendly-urls/plan.md names \u0060resources/js/components/forms/album/AlbumProperties.vue\u0060, but no file or folder \u0060resources/js/components/forms/album/AlbumProperties.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/019-friendly-urls/plan.md"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fbff0e44485a9ea0af985e1032aa6dc4455dc7fd2c4fffa0c3a52e0514e59b8"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/019-friendly-urls/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/019-friendly-urls/plan.md"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"760da4dc3cbc66bbe328cbda6918bb86574b8a09ef48d4c4d5dcd6ba81ff4d7a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/019-friendly-urls/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/019-friendly-urls/plan.md"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d64849eb745332d7b7a72a3d795fe5f1c91a32014648f3938c90aa70d2e4774"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/019-friendly-urls/tasks.md names \u0060tests/Feature_v2/Album/AlbumSlugResolutionTest.php\u0060, but no file or folder \u0060tests/Feature_v2/Album/AlbumSlugResolutionTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/019-friendly-urls/tasks.md"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"6816c50d1b0d865449037da47ba180d383d2e87a364791ef9b62685ed36ba48d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/019-friendly-urls/tasks.md names \u0060tests/Feature_v2/Album/AlbumSlugCrudTest.php\u0060, but no file or folder \u0060tests/Feature_v2/Album/AlbumSlugCrudTest.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/019-friendly-urls/tasks.md"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"30ac45493c99c53ed2a7a2c56695dad89fae7286052a4bcac37f864d35ed5237"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/019-friendly-urls/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/019-friendly-urls/tasks.md"},"region":{"startLine":169}}}],"partialFingerprints":{"codehealthFindingId/v1":"7df9b575ed608e2744b8a62283d21a58cc29fb84d75ce2d35d72503f6ca9cd63"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/019-friendly-urls/tasks.md names \u0060resources/js/components/forms/album/AlbumProperties.vue\u0060, but no file or folder \u0060resources/js/components/forms/album/AlbumProperties.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/019-friendly-urls/tasks.md"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"c04473c684a322196d3989f4026a814f7dd43a2a9ad3238eeec09d48be61075c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/019-friendly-urls/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/019-friendly-urls/tasks.md"},"region":{"startLine":179}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2f4dd4c91e688c1b1edf0afdae2ed6126fdcbbe27e5e262f16fa4443ff38a8e"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/020-raw-upload-support/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/020-raw-upload-support/plan.md"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"de485bff089d95dad0967c9d383699caf694782de0cd5fe27168ecf0c928e3c9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/020-raw-upload-support/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/020-raw-upload-support/plan.md"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"83d1e9635799d192fe51e03f38824635e10c1ace259adb3708bb8288b95cee10"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/020-raw-upload-support/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/020-raw-upload-support/tasks.md"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"903366e66e5f6e5773cec4ed49dcd25f37c995ee09d2fc943833a3b1295b0b21"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/020-raw-upload-support/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/020-raw-upload-support/tasks.md"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"06f40281cf86d3bf8f7f30aaeed53387a332b353723f410d3d98981b4a5a2438"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/021-album-variant-zip/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/021-album-variant-zip/plan.md"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"2aedc26d5729631c1bdf19f39d0b5c88f629f2ffa1dc72c5d7e3bec22453cfa2"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/021-album-variant-zip/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/021-album-variant-zip/plan.md"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"4304c28c6f1762f131b5d379d2d1decc51e3bc33df4cd32df0fa06413eefe9d1"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/021-album-variant-zip/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/021-album-variant-zip/tasks.md"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc19559927b89d979ff0605fd9ac6e39bc4ea40a11446c6899fce8afa0a2502c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/021-album-variant-zip/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/021-album-variant-zip/tasks.md"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"04ca86abad468f4b5dd4177dd34aa51234be0462379dedfb0b078179e17dff5e"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/022-contact-form/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/022-contact-form/plan.md"},"region":{"startLine":375}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc84ebaa8702429fd74892f20576190167fb6e69d2e707d108de0beeb46bbdc0"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/022-contact-form/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/022-contact-form/plan.md"},"region":{"startLine":376}}}],"partialFingerprints":{"codehealthFindingId/v1":"05fc953148e0b317e988efd63c73453d9533fc0ec8655d38758b83fcd4ff020c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/022-contact-form/spec.md names \u0060config/contact.php\u0060, but no file or folder \u0060config/contact.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/022-contact-form/spec.md"},"region":{"startLine":380}}}],"partialFingerprints":{"codehealthFindingId/v1":"dee35d8cc9d599a805dce66eeff8e14d8241572279bffc09b7458dfd3a5570dd"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/022-contact-form/spec.md names \u0060resources/js/pages/Contact.vue\u0060, but no file or folder \u0060resources/js/pages/Contact.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/022-contact-form/spec.md"},"region":{"startLine":402}}}],"partialFingerprints":{"codehealthFindingId/v1":"c87a531d9376dc7569eae1c3a139a99a5acae218b40857ffef54ef97a9b198aa"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/022-contact-form/spec.md names \u0060resources/js/pages/Admin/ContactMessages.vue\u0060, but no file or folder \u0060resources/js/pages/Admin/ContactMessages.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/022-contact-form/spec.md"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7125c23b2ac7392896155032c22340ea564e7122c4d2a627bf5336b54d2c200"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/022-contact-form/spec.md names \u0060resources/js/services/contactService.ts\u0060, but no file or folder \u0060resources/js/services/contactService.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/022-contact-form/spec.md"},"region":{"startLine":416}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a4daa702dfac31ba0c26ce71482ed4b0cc007e36ac188a08460c6c5da6918f2"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/022-contact-form/spec.md names \u0060resources/js/services/admin/contactSettingsService.ts\u0060, but no file or folder \u0060resources/js/services/admin/contactSettingsService.ts\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/022-contact-form/spec.md"},"region":{"startLine":422}}}],"partialFingerprints":{"codehealthFindingId/v1":"df7664f53f5f76d8cfce227b067bcfbff96f725028a23e705b49f1657e688b66"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/022-contact-form/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/022-contact-form/tasks.md"},"region":{"startLine":198}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b9388ce3fd828c4b05f3c7cadab7dec6aee892dd2f85596da23dc56e9303e6c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/022-contact-form/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/022-contact-form/tasks.md"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc4015f3c1173e4acd200e53dbfab6079a173ad18f6271c18a903cfd65381330"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/023-remember-me-login/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/023-remember-me-login/plan.md"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"24621d2fa7b7661b9bea493f82e84de6e428224d47862fd6027eb1497d286738"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/023-remember-me-login/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/023-remember-me-login/plan.md"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"564980a5658d6676acefc2c3a601f41a516a3fa3eeda1ed2b5ec6d35877f60ae"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/023-remember-me-login/plan.md names \u0060lang/en/lychee.php\u0060, but no file or folder \u0060lang/en/lychee.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/023-remember-me-login/plan.md"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2b5e8750ed879a9ddcb9a5365c3e77cf4c6bb0bab94492b55df4f9389435e48"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/023-remember-me-login/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/023-remember-me-login/tasks.md"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f4630fd33b11008b20bf5dd5eef623528944174a0f6d0af7b4aa335bc427916"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/023-remember-me-login/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/023-remember-me-login/tasks.md"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c2ebbe74eb17825c5e26c364a512553697a21406decdf2f5680dce236d1d42a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/023-remember-me-login/tasks.md names \u0060resources/js/components/forms/auth/LoginForm.vue\u0060, but no file or folder \u0060resources/js/components/forms/auth/LoginForm.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/023-remember-me-login/tasks.md"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0a22ccfd44f3cee71b15031662e8486395b3dfff201048fdd272f5d68ed283a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/023-remember-me-login/tasks.md names \u0060lang/en/lychee.php\u0060, but no file or folder \u0060lang/en/lychee.php\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/023-remember-me-login/tasks.md"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"a30c7f73d943317e58f5c05bb09080cb89f1323a8658331889ef2b545a59058f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/024-sync-file-list/plan.md names \u0060tests/Feature/Commands/\u0060, but no file or folder \u0060tests/Feature/Commands\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/024-sync-file-list/plan.md"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"8be1d744caeb6fadd3ecc6bf940f0906e1d99b93a37b59424146ae3a60f02ba6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/025-dynamic-landing-backgrounds/plan.md names \u0060resources/js/views/Landing.vue\u0060, but no file or folder \u0060resources/js/views/Landing.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/025-dynamic-landing-backgrounds/plan.md"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab6b0a2baa369d86ab396e0a2a7a7f9f568fcec09a6ebeff76f3df2d0cd72f28"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/025-dynamic-landing-backgrounds/spec.md names \u0060resources/js/views/Landing.vue\u0060, but no file or folder \u0060resources/js/views/Landing.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/025-dynamic-landing-backgrounds/spec.md"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e53468893aa6996f8b0ca5699c5eacadc80441e00ae975ba95fa8ecdfc74010"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md names \u0060resources/js/views/gallery-panels/Album.vue\u0060, but no file or folder \u0060resources/js/views/gallery-panels/Album.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"6910b489639adcb296465729b5761053acaeba72f6b642b03d81213e146e35d4"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md runs \u0060npm run format   # Auto-format TypeScript/Vue\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"c84dbe576b22259273e11b5eb14dfaecaf22d59b5eb5b53f770ec64b85412495"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md runs \u0060npm run check    # Type checking and linting\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"242441cf682b49ad70467e860028dfdbd1f049f0c0745c5a1becce5b7ecd8320"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md names \u0060docs/specs/4-architecture/features/026-advanced-album-tag-filter/performance-results.md\u0060, but no file or folder \u0060docs/specs/4-architecture/features/026-advanced-album-tag-filter/performance-results.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"80fb432eb74189120f32a6c3421109e78b7d8bf16ae33f2437b492c36fc255fb"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md names \u0060app/Http/Controllers/Gallery/AlbumTagsController\u0060, but no file or folder \u0060app/Http/Controllers/Gallery/AlbumTagsController\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"838d91cc1c333ec118c258a5dc95ed48cec42e9b541f9f8b46e40fd82d22a603"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md names \u0060app/Http/Requests/Album/AlbumTagsRequest\u0060, but no file or folder \u0060app/Http/Requests/Album/AlbumTagsRequest\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a18a8a6fdb5b6df9fe3d9649944aca26d66689f27403418107bfe6e5ae23cb0"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md names \u0060app/Http/Requests/Album/GetAlbumPhotosRequest\u0060, but no file or folder \u0060app/Http/Requests/Album/GetAlbumPhotosRequest\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c058d8ebc7197cd6631ea5248dab784d85f74159796549adcb257f43bd4e153"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md names \u0060app/Repositories/PhotoRepository\u0060, but no file or folder \u0060app/Repositories/PhotoRepository\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"692dc7db9f032b163b9ada4e63d444290e7975eabb0f82a24c3af903ffe2a39b"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md names \u0060resources/js/components/gallery/albumModule/AlbumTagFilter.vue\u0060, but no file or folder \u0060resources/js/components/gallery/albumModule/AlbumTagFilter.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/COMPLETION-SUMMARY.md"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"42443ca0289e62a7927829ea5e540ebe9a0815e1f6c9252f128b33c3e41d6694"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/I7-integration-plan.md names \u0060resources/js/views/gallery-panels/Album.vue\u0060, but no file or folder \u0060resources/js/views/gallery-panels/Album.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/I7-integration-plan.md"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"efdadbd42b1c5944163c56a45d706003a32d9e566535126f29d83be0e88d19b1"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/I7-integration-plan.md runs \u0060npm run format  # Auto-format TypeScript/Vue\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/I7-integration-plan.md"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d7764f802902626d51b53139769776693d9808b15fe60005881edc61ad63f6f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/I7-integration-plan.md runs \u0060npm run check   # Run type checking and linting\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/I7-integration-plan.md"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1cd8a2deabad30ee79cce64a8880b5159b81fd14d886636d027d194009175f8"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/plan.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/plan.md"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"56900424b772955d63b14247a9ef4f452c6d77cbf059f73a38d548eca4dcea48"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/plan.md runs \u0060npm run test:unit -- AlbumTagFilter.spec.ts\u0060, but no package.json declares a \u0060test:unit\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/plan.md"},"region":{"startLine":314}}}],"partialFingerprints":{"codehealthFindingId/v1":"5573b435954efeb0832fc0bce82dd4cadc58372ed758cfdb3d4f04faa5e648ad"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/plan.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/plan.md"},"region":{"startLine":316}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6e8fc75c876c44b147c80632a772db38bd594ecaf4402897b7e733679bb47e9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/spec.md names \u0060resources/js/components/album/\u0060, but no file or folder \u0060resources/js/components/album\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/spec.md"},"region":{"startLine":405}}}],"partialFingerprints":{"codehealthFindingId/v1":"395af9191b1623a715bc5b3eb1093a8bb0f0e5d6d5fb009774cb366f6f95e337"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/tasks.md names \u0060resources/js/views/gallery-panels/Album.vue\u0060, but no file or folder \u0060resources/js/views/gallery-panels/Album.vue\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/tasks.md"},"region":{"startLine":437}}}],"partialFingerprints":{"codehealthFindingId/v1":"bad274c7166d99dfa9c1a7ea3d10c83400de406fa9bf57677bf8caaa747f0e7d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/tasks.md runs \u0060npm run check\u0060, but no package.json declares a \u0060check\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/tasks.md"},"region":{"startLine":506}}}],"partialFingerprints":{"codehealthFindingId/v1":"764a5586406c6049a1c5a1aac87915b551b94f68fa1d54f5aae524cd9fa2c18d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/specs/4-architecture/features/026-advanced-album-tag-filter/tasks.md runs \u0060npm run format\u0060, but no package.json declares a \u0060format\u0060 script. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/specs/4-architecture/features/026-advanced-album-tag-filter/tasks.md"},"region":{"startLine":507}}}],"partialFingerprints":{"codehealthFindingId/v1":"55a2a5b542e537dfc0b04fde8acb9aa5b94d609b8b73639571e7c7424394cb5d"}},{"ruleId":"P4","level":"note","message":{"text":"No release approval gate: Deployment is automated and no gate that pauses it for a human is DECLARED IN THIS REPOSITORY\u0027S PIPELINE FILES. What was read: every file under \u0060.github/workflows/\u0060, \u0060.forgejo/workflows/\u0060, \u0060.gitea/workflows/\u0060, \u0060.azuredevops/\u0060 and \u0060.azure-pipelines/\u0060, plus \u0060.gitlab-ci*\u0060 and \u0060azure-pipelines*\u0060 \u2014 with comment text stripped, so documenting a gate is not declaring one. What would have counted: GitLab\u0027s \u0060when: manual\u0060, CircleCI\u0027s \u0060type: approval\u0060, an Azure \u0060ManualValidation@\u0060 task or an \u0060approvals:\u0060 block, a Jenkins \u0060input\u0060 step, a \u0060uses:\u0060 step naming an approval action, an \u0060environment:\u0060 paired with \u0060reviewers\u0060 / \u0060required_reviewers\u0060 / \u0060protection\u0060 / \u0060wait-timer\u0060 / \u0060deployment_branch_policy\u0060, a draft-release step, a \u0060workflow_dispatch\u0060 promotion, or a release-event gate. \u2605 What this cannot see, because none of it is a file: a GitHub environment whose required reviewers are configured in repo SETTINGS, a branch protection rule, or an organisation deployment policy \u2014 all of them real, enforced gates that live outside the repository. If yours is one of those, this row is wrong and nothing in the tree could have told us. Otherwise: whatever reaches the release trigger goes to production unreviewed, so a mistaken merge or tag is live before anyone can stop it."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"6c11e2dbd483b4b423b95ac61bfcc7af1d55351b28a20d2b1105b31cfe38cc60"}},{"ruleId":"P5","level":"warning","message":{"text":"No DR/backup evidence: A persistence guard (data volume / purge-protection) was found, but no backup, geo-recovery or RTO/RPO controls were evidenced \u2014 a volume that survives a container recreate is not a tested restore from catastrophic loss."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"5daabb38c90b07af65b8738cf94ce884e90a7d8fef810d341de5c186188c8fe0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplication concentrated across 7 sibling directories (322 clone groups): 322 duplicated blocks under resources/js/ have copies in at least two of the sibling directories composables, layouts, services, stores, utils, v7 (\u002B1 more sibling(s) not listed) \u2014 294 of them are reported below, and 28 are counted here but not reported individually: those copies match on shape but no longer clear R10\u0027s bar for an individually reported row \u2014 either they kept neither their own names nor their values, or what was copied is too small to stand on its own (it reports near-exact duplication only, and only of substantial extent). What this row states is the concentration, which the detector measured over all 322 and which does not depend on how exactly each block\u0027s copies still match. That concentration is one structural fact, not 322 local ones: the siblings replicate behaviour none of them owns, which is the shape of a missing shared module \u2014 a common library every sibling imports \u2014 rather than 322 separate extractions. Check first whether the siblings are deliberately standalone deliverables (scaffold templates, demo apps that must stay copy-pasteable); where they are, the duplication is the design and the per-block rows are the ones to act on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/PersonDetail.vue"},"region":{"startLine":181}}}],"partialFingerprints":{"codehealthFindingId/v1":"bedf8d8ff223fc6ad935d4fd0e95ce57572f7963c30273a778fdee93fcb658ab"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplication concentrated across 4 sibling directories (7 clone groups): 7 duplicated blocks under resources/js/v8/ have copies in at least two of the sibling directories components, composables, utils, views \u2014 5 of them are reported below, and 2 are counted here but not reported individually: those copies match on shape but no longer clear R10\u0027s bar for an individually reported row \u2014 either they kept neither their own names nor their values, or what was copied is too small to stand on its own (it reports near-exact duplication only, and only of substantial extent). What this row states is the concentration, which the detector measured over all 7 and which does not depend on how exactly each block\u0027s copies still match. That concentration is one structural fact, not 7 local ones: the siblings replicate behaviour none of them owns, which is the shape of a missing shared module \u2014 a common library every sibling imports \u2014 rather than 7 separate extractions. Check first whether the siblings are deliberately standalone deliverables (scaffold templates, demo apps that must stay copy-pasteable); where they are, the duplication is the design and the per-block rows are the ones to act on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/tagModule/TagPanel.vue"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae1c66c561144178738eb73ef1a9bbfcf42a505313d521969052d3773df64c2c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplication concentrated across 6 sibling directories (7 clone groups): 7 duplicated blocks under resources/js/v8/components/ have copies in at least two of the sibling directories drawers, forms, gallery, headers, modals, renamer \u2014 2 of them are reported below, and 5 are counted here but not reported individually: those copies match on shape but no longer clear R10\u0027s bar for an individually reported row \u2014 either they kept neither their own names nor their values, or what was copied is too small to stand on its own (it reports near-exact duplication only, and only of substantial extent). What this row states is the concentration, which the detector measured over all 7 and which does not depend on how exactly each block\u0027s copies still match. That concentration is one structural fact, not 7 local ones: the siblings replicate behaviour none of them owns, which is the shape of a missing shared module \u2014 a common library every sibling imports \u2014 rather than 7 separate extractions. Check first whether the siblings are deliberately standalone deliverables (scaffold templates, demo apps that must stay copy-pasteable); where they are, the duplication is the design and the per-block rows are the ones to act on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoEdit.vue"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2a05f333871df4e1ef9ac0fba8992ec1cc8eb77bc1aa0d968fdff9feedcbf2a"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (299 identical lines \u00D7 2 files): resources/js/v7/views/face-recog/PersonDetail.vue:181 \u00B7 resources/js/v8/views/face-recog/PersonDetail.vue:187 \u2014 these 2 files are line-for-line copies of one another \u2014 299 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/PersonDetail.vue"},"region":{"startLine":181}}}],"partialFingerprints":{"codehealthFindingId/v1":"1585df0e958b1a367200db544d1f199724c0f4184e6383c7da950c8e80462fe4"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (288 matched lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Search.vue:175 \u00B7 resources/js/v8/views/gallery-panels/Search.vue:188 \u2014 the two spans are one implementation copied and then locally edited \u2014 2026 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Search.vue"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"57209ea01c0286de485ef88578e6166019d0347aa0bc4952309f7b35137d34ac"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (269 identical lines \u00D7 2 files): resources/js/composables/contextMenus/contextMenu.ts:1 \u00B7 resources/js/v8/composables/contextMenus/contextMenu.ts:1 \u2014 these 2 files are line-for-line copies of one another \u2014 269 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d449ee6d949b67e726613763f6dc43c2c56f4e37ddfe02a921fa5237ed57d3f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (230 matched lines \u00D7 2 locations): resources/js/v7/components/forms/album/AlbumProperties.vue:393 \u00B7 resources/js/v8/components/forms/album/AlbumProperties.vue:220 \u2014 the two spans are one implementation copied and then locally edited \u2014 1952 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumProperties.vue"},"region":{"startLine":393}}}],"partialFingerprints":{"codehealthFindingId/v1":"89aa9d09f4fa07b4200ffb30574b886be90b8e0cdb375ee0ad062260eadcf729"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (216 matched lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Album.vue:174 \u00B7 resources/js/v8/views/gallery-panels/Album.vue:178 \u2014 the two spans are one implementation copied and then locally edited \u2014 1664 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Album.vue"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"612d7c5433661f0751aee640d612f754bbcb19a1ee7e11c485aeb7264ae65f2a"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (203 identical lines \u00D7 2 files): resources/js/v7/views/face-recog/FaceMaintenance.vue:266 \u00B7 resources/js/v8/views/face-recog/FaceMaintenance.vue:273 \u2014 these 2 files are line-for-line copies of one another \u2014 203 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceMaintenance.vue"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"a853714ce9ef84d6cefb685bb78a9db64c7ea50373f8a393cfdd9664392152f9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (200 matched lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/AlbumPanel.vue:298 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumPanel.vue:400 \u2014 the two spans are one implementation copied and then locally edited \u2014 1418 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumPanel.vue"},"region":{"startLine":298}}}],"partialFingerprints":{"codehealthFindingId/v1":"e171fb606bfc3897079ae103340eba10f8800f58abd558d2372c310aa4a6aef2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (195 matched lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Timeline.vue:217 \u00B7 resources/js/v8/views/gallery-panels/Timeline.vue:281 \u2014 the two spans are one implementation copied and then locally edited \u2014 1280 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Timeline.vue"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"199772f55d9589334fbae14dfd7a95742b0a37941e1a43ef9f9eebb36fe50309"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (188 identical lines \u00D7 2 files): resources/js/v7/components/forms/album/EmbedCodeDialog.vue:138 \u00B7 resources/js/v8/components/forms/album/EmbedCodeDialog.vue:152 \u2014 these 2 files are line-for-line copies of one another \u2014 188 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/EmbedCodeDialog.vue"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"005955f1a163d767c6d6a494bce8c65abc6e3dfd14b086a39dc7127150883ad7"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (140 matched lines \u00D7 2 locations): resources/js/v7/views/face-recog/FaceClusters.vue:229 \u00B7 resources/js/v8/views/face-recog/FaceClusters.vue:292 \u2014 the two spans are one implementation copied and then locally edited \u2014 1267 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbc966904964767a9bd67748ff0b60277e14b3eb3c5df045c0bca144bad89c93"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (138 matched lines \u00D7 2 locations): resources/js/v7/components/drawers/LiveMetrics.vue:58 \u00B7 resources/js/v8/components/drawers/LiveMetrics.vue:71 \u2014 the two spans are one implementation copied and then locally edited \u2014 1038 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/LiveMetrics.vue"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"b85487dcec6dda3a2a1c13d25fcbb8d3a09b972dbfb93eef8c172eb5df872339"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (136 identical lines \u00D7 2 files): resources/js/v7/components/settings/General.vue:236 \u00B7 resources/js/v8/components/settings/General.vue:254 \u2014 these 2 files are line-for-line copies of one another \u2014 136 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fddc9d657d857cea6b35396cab2961b9ae47f43b8823663987555bd4a5048cc"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (130 matched lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Tag.vue:122 \u00B7 resources/js/v8/views/gallery-panels/Tag.vue:120 \u2014 the two spans are one implementation copied and then locally edited \u2014 872 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Tag.vue"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bb53429af3c9bdc3a9452868484267cea69d827e1c7fe33f6ce49b9b13e079f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (126 matched lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Albums.vue:274 \u00B7 resources/js/v8/views/gallery-panels/Albums.vue:289 \u2014 the two spans are one implementation copied and then locally edited \u2014 846 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Albums.vue"},"region":{"startLine":274}}}],"partialFingerprints":{"codehealthFindingId/v1":"d75153e2c75c91e0f78c790792ae6bddb0061b399ec0e13204edc775bab5d312"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (124 matched lines \u00D7 2 locations): resources/js/v7/components/forms/upload/UploadingLine.vue:57 \u00B7 resources/js/v8/components/forms/upload/UploadingLine.vue:118 \u2014 the two spans are one implementation copied and then locally edited \u2014 852 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/upload/UploadingLine.vue"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"6979d347c309431fb4458775ef7c9cc4ef6f463d8d8cf4b47393a06ae1f38dfc"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (124 matched lines \u00D7 2 locations): resources/js/v7/views/face-recog/FaceClusters.vue:437 \u00B7 resources/js/v8/views/face-recog/FaceClusters.vue:607 \u2014 the two spans are one implementation copied and then locally edited \u2014 965 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":437}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f0de354bec764cf41f6d64a708671f9baa7ae411a93b50828a311d3fb306c0c"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (121 identical lines \u00D7 2 files): resources/js/v7/components/gallery/albumModule/AlbumHeaderPanel.vue:123 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumHeaderPanel.vue:137 \u2014 these 2 files are line-for-line copies of one another \u2014 121 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumHeaderPanel.vue"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"d721c4da3417e6a86cd191ce8943662a16457f128861d6a698e5ecb228129c18"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (116 identical lines \u00D7 2 files): resources/js/v7/components/renamer/RenamerRuleModal.vue:174 \u00B7 resources/js/v8/components/renamer/RenamerRuleModal.vue:139 \u2014 these 2 files are line-for-line copies of one another \u2014 116 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/renamer/RenamerRuleModal.vue"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"adde61db1fb29347a4c206317549d833fe077e9ece07b65307433a72267c8304"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (108 identical lines \u00D7 2 files): resources/js/v7/components/forms/gallery-dialogs/MoveDialog.vue:33 \u00B7 resources/js/v8/components/forms/gallery-dialogs/MoveDialog.vue:45 \u2014 these 2 files are line-for-line copies of one another \u2014 108 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/gallery-dialogs/MoveDialog.vue"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"afb3a0be505508bace24fcc9e3ac4f1ca979d74e29ba13a0ba254872d4a3c6e8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (107 matched lines \u00D7 2 locations): resources/js/v7/components/modals/UploadPanel.vue:122 \u00B7 resources/js/v8/components/modals/UploadPanel.vue:125 \u2014 the two spans are one implementation copied and then locally edited \u2014 869 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/UploadPanel.vue"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"795d5f7e1984aac6b269044d1587cf1a038f7bd1e0923c83bc36c001cf2b4229"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (105 lines \u00D7 2 locations): resources/js/v7/views/admin/Moderation.vue:167 \u00B7 resources/js/v8/views/admin/Moderation.vue:180 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Moderation.vue"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"16edfe23a9fe292ab47528547174f8bdb03166ecec35f9cbdd10cabf54d272d0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (103 matched lines \u00D7 2 locations): resources/js/v7/views/admin/Settings.vue:79 \u00B7 resources/js/v8/views/admin/Settings.vue:108 \u2014 the two spans are one implementation copied and then locally edited \u2014 715 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Settings.vue"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4d8692ddb46dc6dcc92481caf1e8fa9c3f4503aac3fc9f0929b7cfefe8f60b9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (97 lines \u00D7 2 locations): resources/js/v7/views/admin/Jobs.vue:51 \u00B7 resources/js/v8/views/admin/Jobs.vue:103 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Jobs.vue"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d3569fd78fe26c9c2bd209e3c4e5e787b6c4520cb22504ff969c6597529a410"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (97 identical lines \u00D7 2 files): resources/js/v7/views/webshop/OrderDownload.vue:206 \u00B7 resources/js/v8/views/webshop/OrderDownload.vue:214 \u2014 these 2 files are line-for-line copies of one another \u2014 97 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderDownload.vue"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"f45edc8c71079e8fca018312509e2527de82edd4d6f694d7bdb070648dd0a12b"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (96 identical lines \u00D7 2 files): resources/js/v7/components/forms/album/AlbumPurchasable.vue:59 \u00B7 resources/js/v8/components/forms/album/AlbumPurchasable.vue:60 \u2014 these 2 files are line-for-line copies of one another \u2014 96 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumPurchasable.vue"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3e9eca7c212156a3cbeaa4bddfe39f5994d4bd70a3039bb324c45c68f5506b7"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (95 identical lines \u00D7 2 files): resources/js/v7/components/forms/users/CreateEditUser.vue:91 \u00B7 resources/js/v8/components/forms/users/CreateEditUser.vue:84 \u2014 these 2 files are line-for-line copies of one another \u2014 95 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/users/CreateEditUser.vue"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"72666718779cc78bc6d820570df4001236d0a7fb3b8212922f470a138f52bc03"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (90 lines \u00D7 2 locations): resources/js/v7/components/forms/search/AdvancedSearchPanel.vue:222 \u00B7 resources/js/v8/components/forms/search/AdvancedSearchPanel.vue:275 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7db90a9a451fe8314389df105fe1abc563ddd27b70af98ace9cb2aaf8a24e8e"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (89 identical lines \u00D7 2 files): resources/js/v7/components/modals/CameraCapture.vue:70 \u00B7 resources/js/v8/components/modals/CameraCapture.vue:82 \u2014 these 2 files are line-for-line copies of one another \u2014 89 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/CameraCapture.vue"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ebd233578b64900c93f37c70727c400b27c941b94e2172c35a5acb2482a4aaf"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (89 matched lines \u00D7 2 locations): resources/js/v7/views/admin/UserGroups.vue:126 \u00B7 resources/js/v8/views/admin/UserGroups.vue:118 \u2014 the two spans are one implementation copied and then locally edited \u2014 702 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/UserGroups.vue"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa71a420dc460c066a271010f4b7ad83a03615fb114341ea4703f4aca98bc774"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (88 matched lines \u00D7 2 locations): resources/js/v7/components/forms/album/ApplyRenamerDialog.vue:121 \u00B7 resources/js/v8/components/forms/album/ApplyRenamerDialog.vue:157 \u2014 the two spans are one implementation copied and then locally edited \u2014 609 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/ApplyRenamerDialog.vue"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"72814d54aa4fa5ec3eb1942b76c2541ae981f6ac6cbf7b48f44d8b6796b48925"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (87 identical lines \u00D7 2 files): resources/js/v7/components/pagination/PaginationInfiniteScroll.vue:8 \u00B7 resources/js/v8/components/pagination/PaginationInfiniteScroll.vue:8 \u2014 these 2 files are line-for-line copies of one another \u2014 87 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/pagination/PaginationInfiniteScroll.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"f57ee35f2885bb24d23e609bc00bc7a4e49397180ca68409a4622e96a97b9733"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (84 lines \u00D7 2 locations): resources/js/v7/components/drawers/PhotoDetails.vue:321 \u00B7 resources/js/v8/components/drawers/PhotoDetails.vue:311 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/PhotoDetails.vue"},"region":{"startLine":321}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f816794dc47309a51160cb0ccb437e2b96c6f1fd110cc0643d44227c195f336"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (83 matched lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Flow.vue:55 \u00B7 resources/js/v8/views/gallery-panels/Flow.vue:104 \u2014 the two spans are one implementation copied and then locally edited \u2014 587 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Flow.vue"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"01b523e71ebf7357d852be1ed7a500248e2e07c1d1685953cbad0c4f030b626d"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (82 identical lines \u00D7 2 files): resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListViewVirtual.vue:59 \u00B7 resources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbGridVirtual.vue:85 \u2014 these 2 files are line-for-line copies of one another \u2014 82 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListViewVirtual.vue"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"60fbdbd66e525b2db1fa6ebccae58d09a4ec40e48136c89ee2ceca10649871cd"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (80 identical lines \u00D7 2 files): resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootGridVirtual.vue:89 \u00B7 resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootListViewVirtual.vue:60 \u2014 these 2 files are line-for-line copies of one another \u2014 80 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootGridVirtual.vue"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"52fe9e7ac1266add89608d7c374d9f6b96f285cf40ed599c272de1e98961bd1b"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (78 identical lines \u00D7 2 files): resources/js/v7/views/RegisterPage.vue:61 \u00B7 resources/js/v8/views/RegisterPage.vue:54 \u2014 these 2 files are line-for-line copies of one another \u2014 78 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/RegisterPage.vue"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d73889c537a4bfe1e7b9ca19b4848c181ba77fe0b0312894ea06cbc27768f13"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (77 matched lines \u00D7 2 locations): resources/js/v7/components/drawers/PhotoEdit.vue:123 \u00B7 resources/js/v8/components/drawers/PhotoEdit.vue:94 \u2014 the two spans are one implementation copied and then locally edited \u2014 754 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/PhotoEdit.vue"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b26cb82c5399cb23bcbf47eafc27f3fd4a34ecf4e45ccdc3f13f1b87c6b9d4d"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (76 identical lines \u00D7 2 files): resources/js/v7/views/admin/AdminDashboard.vue:172 \u00B7 resources/js/v8/views/admin/AdminDashboard.vue:134 \u2014 these 2 files are line-for-line copies of one another \u2014 76 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/AdminDashboard.vue"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"12916dd061de3ea5f4ed2184335a6ac66f43dde5a404170913eddb819393bfaf"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (75 identical lines \u00D7 2 files): resources/js/v7/views/Contact.vue:128 \u00B7 resources/js/v8/components/forms/contact/ContactForm.vue:121 \u2014 these 2 files are line-for-line copies of one another \u2014 75 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Contact.vue"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"8509372d5aed89076e842987538c9f2cf312f97def1a1f4dd99fc4f68c6b6595"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (70 identical lines \u00D7 2 files): resources/js/v7/components/forms/gallery-dialogs/DeleteDialog.vue:24 \u00B7 resources/js/v8/components/forms/gallery-dialogs/DeleteDialog.vue:33 \u2014 these 2 files are line-for-line copies of one another \u2014 70 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/gallery-dialogs/DeleteDialog.vue"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"7376bdc6991be3281ab7c351eb3f8aa80963b87fbe0b05cfc5ade04d1bd3eb4d"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (68 identical lines \u00D7 2 files): resources/js/v7/components/forms/card/CardForm.vue:65 \u00B7 resources/js/v8/components/forms/card/CardForm.vue:62 \u2014 these 2 files are line-for-line copies of one another \u2014 68 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/card/CardForm.vue"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"5242ba52e882b457a16f420871fe1ef6362d5850185053b1e51649ad7b738a96"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (68 identical lines \u00D7 2 files): resources/js/v7/components/gallery/albumModule/AlbumHero.vue:180 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumHero.vue:183 \u2014 these 2 files are line-for-line copies of one another \u2014 68 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"51fbefa171b4b470fa4ca994fd4572112e01be816ae787def37291e4b247e0a1"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (68 identical lines \u00D7 2 files): resources/js/v7/components/modals/DownloadPhoto.vue:39 \u00B7 resources/js/v8/components/modals/DownloadPhoto.vue:31 \u2014 these 2 files are line-for-line copies of one another \u2014 68 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/DownloadPhoto.vue"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd45865ffa3a0d82bd9e61e377f87f763747209a9699deee7510ea2019c9be4d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (68 matched lines \u00D7 2 locations): resources/js/v7/views/face-recog/People.vue:92 \u00B7 resources/js/v8/views/face-recog/People.vue:116 \u2014 the two spans are one implementation copied and then locally edited \u2014 575 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/People.vue"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f3fe7aeeca8926259926956b8bf39eaecd7097ba557de602f95dd5ce4b70713"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (67 matched lines \u00D7 2 locations): resources/js/layouts/PhotoLayout.ts:10 \u00B7 resources/js/v8/layouts/PhotoLayout.ts:11 \u2014 the two spans are one implementation copied and then locally edited \u2014 326 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/PhotoLayout.ts"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8ca8df33e24b73b9620402956dd245c721076ad0e41f064ef89e001ad174711"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (67 identical lines \u00D7 2 files): resources/js/v7/components/modals/ImportFromServer.vue:112 \u00B7 resources/js/v8/components/modals/ImportFromServer.vue:84 \u2014 these 2 files are line-for-line copies of one another \u2014 67 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/ImportFromServer.vue"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e66d8aaf315de71c4799dce291bd3ec15b611a780cb424e581a0e76c301cb5a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (66 matched lines \u00D7 2 locations): resources/js/v7/components/forms/group/AddUserGroupModal.vue:72 \u00B7 resources/js/v8/components/forms/group/AddUserGroupModal.vue:55 \u2014 the two spans are one implementation copied and then locally edited \u2014 475 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/group/AddUserGroupModal.vue"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"7476c36b264e863614cfb8aba45568d403bbf85580872fe838a08fc7b501d557"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (65 identical lines \u00D7 2 files): resources/js/v7/components/forms/sharing/BulkSharingModal.vue:107 \u00B7 resources/js/v8/components/forms/sharing/BulkSharingModal.vue:76 \u2014 these 2 files are line-for-line copies of one another \u2014 65 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/sharing/BulkSharingModal.vue"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"f217c2e7c40c44f4038b7589ab93b79cc08cc21b79bb571e1ba8203d5088b6d9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (65 lines \u00D7 2 locations): resources/js/v7/views/RenamerRules.vue:136 \u00B7 resources/js/v8/views/RenamerRules.vue:126 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/RenamerRules.vue"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3b323e9792b695e490d88137c9f030bfc5d57746d45d408e47001566f8ffbf5"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (63 identical lines \u00D7 2 files): resources/js/v7/components/gallery/photoModule/Dock.vue:73 \u00B7 resources/js/v8/components/gallery/photoModule/Dock.vue:52 \u2014 these 2 files are line-for-line copies of one another \u2014 63 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/Dock.vue"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"306e4b764be8e603e64b2d7c042cf7899bda390007cd787a639e9fa7dae953fa"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (62 lines \u00D7 2 locations): resources/js/v7/components/forms/upload/DropBoxChooser.vue:11 \u00B7 resources/js/v8/components/forms/upload/DropBoxChooser.vue:12 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/upload/DropBoxChooser.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"89556e4e5c2e5a98f4df20603ffa81f860e090cfb3d62797c5b5b70f3edb659a"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (61 identical lines \u00D7 2 files): resources/js/v7/components/gallery/photoModule/PhotoPanel.vue:45 \u00B7 resources/js/v8/components/gallery/photoModule/PhotoPanel.vue:60 \u2014 these 2 files are line-for-line copies of one another \u2014 61 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoPanel.vue"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9b6404b0807a7dd9c3561ac74fd7ec42468cc98819b0b55e0632b2a28de984e"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (60 identical lines \u00D7 2 files): resources/js/v7/components/forms/profile/SetLogin.vue:74 \u00B7 resources/js/v8/components/forms/profile/SetLogin.vue:83 \u2014 these 2 files are line-for-line copies of one another \u2014 60 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetLogin.vue"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f755cb847f3a2d7d809a772d3f17b76decb75fa9bce90a7f1ec0b70320f137d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (60 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/HeaderFocusPicker.vue:37 \u00B7 resources/js/v8/components/gallery/albumModule/HeaderFocusPicker.vue:37 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/HeaderFocusPicker.vue"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"be394d8c4b2e605276ade0938b51da534f6cab304c081037229cf36079fdf94d"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (58 identical lines \u00D7 2 files): resources/js/v7/components/forms/album/Unlock.vue:31 \u00B7 resources/js/v8/components/forms/album/Unlock.vue:30 \u2014 these 2 files are line-for-line copies of one another \u2014 58 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/Unlock.vue"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2728b412c6ef64bfe0ddb092837147639ab988cfce772384df955248fef40d3"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (58 identical lines \u00D7 2 files): resources/js/v7/components/forms/auth/LoginForm.vue:108 \u00B7 resources/js/v8/components/forms/auth/LoginForm.vue:79 \u2014 these 2 files are line-for-line copies of one another \u2014 58 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/auth/LoginForm.vue"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"db884cb77af2aaef48d8c32692b41df11df54211efbfad4b5b359588667a56c0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (58 lines \u00D7 2 locations): resources/js/v7/components/gallery/tagModule/TagPanel.vue:77 \u00B7 resources/js/v8/components/gallery/tagModule/TagPanel.vue:65 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/tagModule/TagPanel.vue"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"6436598e4a3c4685b226d72b9963deca453c874380f2a01f983100f6972ce00b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (57 lines \u00D7 2 locations): resources/js/v7/components/modals/faceRecog/SelfieClaimModal.vue:72 \u00B7 resources/js/v8/components/modals/faceRecog/SelfieClaimModal.vue:85 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/faceRecog/SelfieClaimModal.vue"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d6a8dedf0d0f22333e9529c18abb27fc32014804dd128e02fd0c5f7de629529"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (57 identical lines \u00D7 2 files): resources/js/v7/views/DuplicatesFinder.vue:100 \u00B7 resources/js/v8/views/DuplicatesFinder.vue:93 \u2014 these 2 files are line-for-line copies of one another \u2014 57 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/DuplicatesFinder.vue"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"710013e886c9f996b35fc5be801ffa018624b5c4a8e841a102b2838e284493f8"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (56 identical lines \u00D7 2 files): resources/js/v7/components/forms/gallery-dialogs/AlbumMergeDialog.vue:36 \u00B7 resources/js/v8/components/forms/gallery-dialogs/AlbumMergeDialog.vue:48 \u2014 these 2 files are line-for-line copies of one another \u2014 56 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/gallery-dialogs/AlbumMergeDialog.vue"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d56587458e631d4c965760d9ede55e0c95c29f76ced289a52ab8db78c63393f"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (55 identical lines \u00D7 2 files): resources/js/v7/components/forms/profile/SetSharedAlbumsVisibility.vue:46 \u00B7 resources/js/v8/components/forms/profile/SetSharedAlbumsVisibility.vue:37 \u2014 these 2 files are line-for-line copies of one another \u2014 55 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetSharedAlbumsVisibility.vue"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"367d6dc2b5648b97f7e27a74eb3fda7a0b85d05cf54ea469c3d3c155a64d351f"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (55 identical lines \u00D7 2 files): resources/js/v7/components/gallery/albumModule/PhotoThumbPanelList.vue:30 \u00B7 resources/js/v8/components/gallery/albumModule/PhotoThumbPanelList.vue:35 \u2014 these 2 files are line-for-line copies of one another \u2014 55 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanelList.vue"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe7751229a24ca255571d7c5c78e266793d5f79d32097c0125675df72ec84e19"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (54 lines \u00D7 2 locations): resources/js/composables/selections/selections.ts:118 \u00B7 resources/js/composables/selections/selections.ts:201 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/selections/selections.ts"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff5fa30a346b972ef39c3d6b58270124eb51ac3cb566a5eff5970b72d8157ef1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (53 lines \u00D7 2 locations): resources/js/v7/components/forms/photo/PhotoCopyDialog.vue:53 \u00B7 resources/js/v8/components/forms/photo/PhotoCopyDialog.vue:66 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/photo/PhotoCopyDialog.vue"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"f62749fe97a3eb8de4be784471d7c29a355894fff6fc812eb479d3b17074d84b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (52 lines \u00D7 2 locations): resources/js/v7/components/forms/webhooks/WebhookFormDialog.vue:174 \u00B7 resources/js/v8/components/forms/webhooks/WebhookFormDialog.vue:177 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/webhooks/WebhookFormDialog.vue"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4e97a62c5180d75c5b650c05ec40b4bd23eed0e0e280767a2c9d6748bb5359c"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (51 identical lines \u00D7 2 files): resources/js/v7/components/forms/gallery-dialogs/RenameDialog.vue:25 \u00B7 resources/js/v8/components/forms/gallery-dialogs/RenameDialog.vue:31 \u2014 these 2 files are line-for-line copies of one another \u2014 51 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/gallery-dialogs/RenameDialog.vue"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"5996bb5cfb3a91b8136f181c5a6052cdd9faf871766a6c551e50b36de4cc9a81"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (51 identical lines \u00D7 2 files): resources/js/v7/components/maintenance/MaintenanceGenSizevariants.vue:28 \u00B7 resources/js/v8/components/maintenance/MaintenanceGenSizevariants.vue:15 \u2014 these 2 files are line-for-line copies of one another \u2014 51 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceGenSizevariants.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c2c48bb4767f5a0290bf304905aede3199023fa0e68e9790d502a3b5dc6faaa"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (51 identical lines \u00D7 2 files): resources/js/v7/components/modals/DownloadAlbum.vue:60 \u00B7 resources/js/v8/components/modals/DownloadAlbum.vue:99 \u2014 these 2 files are line-for-line copies of one another \u2014 51 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/DownloadAlbum.vue"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"10817db78e7467074a106c2ce78cce822bbc105d1d0a01ca82f2a1b6f84c40b0"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (50 identical lines \u00D7 2 files): resources/js/composables/album/uploadEvents.ts:1 \u00B7 resources/js/v8/composables/album/uploadEvents.ts:1 \u2014 these 2 files are line-for-line copies of one another \u2014 50 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/uploadEvents.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbaab385088a62a8e5a3858235df78f78d352fe4d346ac054f822e3dbd42ef0b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (50 lines \u00D7 2 locations): resources/js/v7/components/forms/album/AlbumCreateShareDialog.vue:73 \u00B7 resources/js/v8/components/forms/album/AlbumCreateShareDialog.vue:76 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumCreateShareDialog.vue"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"5df20ae0cfa5fca5898b3bd42d1b949a713fd2978b43f3f7deded0a3194d49c2"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (50 identical lines \u00D7 2 files): resources/js/v7/components/forms/card/Card.vue:96 \u00B7 resources/js/v8/components/forms/card/Card.vue:96 \u2014 these 2 files are line-for-line copies of one another \u2014 50 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/card/Card.vue"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfb195dbd912acad3ae1b24e2b89e769fc148c1805273589c112ed41cb78bdc3"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (49 lines \u00D7 2 locations): resources/js/v7/components/forms/sharing/ShareLine.vue:35 \u00B7 resources/js/v8/components/forms/sharing/ShareLine.vue:34 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/sharing/ShareLine.vue"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d10442a9e5d4ef1f2e24cb41338d2d1b306facf0fd0ead0ef69b5e59c6fde06"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (48 matched lines \u00D7 2 locations): resources/js/stores/AlbumState.ts:151 \u00B7 resources/js/stores/AlbumState.ts:844 \u2014 the two spans are one implementation copied and then locally edited \u2014 390 tokens are still identical, in the same order in both spans, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumState.ts"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c717eb4a96d12676d0d962119651f8dc6ec3933b2deeb1e25c0d404af504a6d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (48 lines \u00D7 2 locations): resources/js/v7/components/forms/photo/PhotoTagDialog.vue:58 \u00B7 resources/js/v8/components/forms/photo/PhotoTagDialog.vue:46 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/photo/PhotoTagDialog.vue"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"2556d71e37e16e00f488d431a2776cc1c97e5ba8c33a3325e933ec651fea6eba"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (47 matched lines \u00D7 2 locations): resources/js/services/album-service.ts:269 \u00B7 resources/js/services/photo-service.ts:54 \u2014 the two spans are one implementation copied and then locally edited \u2014 490 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/album-service.ts"},"region":{"startLine":269}}}],"partialFingerprints":{"codehealthFindingId/v1":"380657c8affc2b1261c0ec18a0f9f97a03dd34b1a46ccf7c8010d3ee2d8e1ef4"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (47 lines \u00D7 2 locations): resources/js/v7/views/admin/shop/PrintPixelSizesAdmin.vue:124 \u00B7 resources/js/v8/views/admin/shop/PrintPixelSizesAdmin.vue:118 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/shop/PrintPixelSizesAdmin.vue"},"region":{"startLine":124}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ad02476b7e8f72ba853cf1c823a6e10727eac899e6bde6fe5e48c7f224139f8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (47 lines \u00D7 2 locations): resources/js/v7/views/face-recog/People.vue:177 \u00B7 resources/js/v8/views/face-recog/People.vue:218 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/People.vue"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"03272a40bd2faadb8a94e178c24b6c84edba5bb480bdf30eb466e3ffd60223cd"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (46 lines \u00D7 2 locations): resources/js/composables/contextMenus/leftMenu.ts:207 \u00B7 resources/js/v8/composables/contextMenus/leftMenu.ts:226 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of DECLARATIONS inside a construct \u2014 the members of a type, or the entries of an object or array literal \u2014 with no statement anywhere in it. Do not read this as an extract-a-helper row: nothing here executes, so there is no call site, and a call expression cannot stand where a member declaration or a literal\u0027s entry was. What repeats is a SHAPE, and which shape decides the move. Where the copies declare the same members, the repetition is a missing common ancestor: give it a base type, an interface both extend, a generic instantiated twice, or \u2014 where the copies are a literal\u0027s entries rather than a type\u0027s members \u2014 one shared constant each site spreads or refers to, so the set is written once. Where they declare DIFFERENT members and only the form is shared \u2014 a decorator and its options, an annotation, a registration table\u0027s keys \u2014 the form is prescribed by a framework or a schema rather than copied, and the only collapse available is to generate the declarations from that schema; where you do not own the generator, this is the cost of the framework and there is nothing to extract. Check which of the two it is before acting: these copies still drift apart the first time only one of them is edited, which is why the repetition is reported, but the sentence to act on is not the same in both cases."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7443e27e123f7d3f93bd339678524720730f597b5578323e67e72d8a9c65f56"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (46 lines \u00D7 3 locations): resources/js/v7/components/forms/album/AlbumCreateShareDialog.vue:73 \u00B7 resources/js/v7/components/forms/sharing/CreateSharing.vue:40 \u00B7 resources/js/v8/components/forms/album/AlbumCreateShareDialog.vue:76 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumCreateShareDialog.vue"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"848bdeae1585153c52d7b1ec1014e62d6ea35abef6c11741e1e14f98de189613"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (46 lines \u00D7 2 locations): resources/js/v7/components/forms/search/SearchBox.vue:25 \u00B7 resources/js/v8/components/forms/search/SearchBox.vue:29 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/SearchBox.vue"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"6914130c1fcb4774c678b94d1ddb24243ffc7c691f1e542484a2e8f8778f85f5"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (45 lines \u00D7 2 locations): resources/js/v8/components/headers/AlbumsHeader.vue:212 \u00B7 resources/js/v8/components/headers/TimelineHeader.vue:161 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/AlbumsHeader.vue"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"d24a120942475f8bda4518f06295d50a0bee8375062f4aab69a548cc67bafd3f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (44 matched lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumbImage.vue:35 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/AlbumThumbImage.vue:50 \u2014 the two spans are one implementation copied and then locally edited \u2014 359 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumbImage.vue"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4f57bafc02a4169a9c8df6770f41a13847d5fb997d531e1b8cf8052aeb1d29f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (44 lines \u00D7 2 locations): resources/js/v7/components/maintenance/MaintenanceDestroyDismissedFaces.vue:38 \u00B7 resources/js/v8/components/maintenance/MaintenanceDestroyDismissedFaces.vue:23 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceDestroyDismissedFaces.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d22e4a024aa052d5e23d01cab36767a61e8cabd2943cf647df80a1a1d9ec644"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (44 lines \u00D7 2 locations): resources/js/v7/components/maintenance/MaintenanceResetFaceScanStatus.vue:38 \u00B7 resources/js/v8/components/maintenance/MaintenanceResetFaceScanStatus.vue:23 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceResetFaceScanStatus.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7f418f6acec1a9eb5a1b4e0468532031b5f6577d1b466447ee804efe341ceba"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (44 lines \u00D7 2 locations): resources/js/v7/views/BulkAlbumEdit.vue:508 \u00B7 resources/js/v8/views/BulkAlbumEdit.vue:598 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":508}}}],"partialFingerprints":{"codehealthFindingId/v1":"9873533cba1ced8aae21168109a5346f20b363c4a669038fc9e01f6c4cb96872"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (44 matched lines \u00D7 2 locations): resources/js/v7/views/Error.vue:49 \u00B7 resources/js/v8/views/Error.vue:41 \u2014 the two spans are one implementation copied and then locally edited \u2014 265 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Error.vue"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f646187c855f83b5f31b7167476a1a2661310ea819032d02c81e5a8a0bf0e47"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (43 lines \u00D7 2 locations): resources/js/v7/components/forms/album/AlbumCreateDialog.vue:49 \u00B7 resources/js/v8/components/forms/album/AlbumCreateDialog.vue:48 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumCreateDialog.vue"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb0262c8deb44809f6af01cc94c9ac5e76cd9ae08bed16d8ee91d37b1002d72c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (43 lines \u00D7 2 locations): resources/js/v7/components/forms/album/AlbumShare.vue:68 \u00B7 resources/js/v8/components/forms/album/AlbumShare.vue:81 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumShare.vue"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"76e30771ca5dd68abac2c3105b2e35edda87c51feb2689c686f464aee9d788a0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (43 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/AlbumThumbPanel.vue:113 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumThumbPanel.vue:99 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumThumbPanel.vue"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"7dac986cf6851d1fc13887ddc3be1dfd01d502b5a990ec2f109e4255b1d0e160"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (43 lines \u00D7 2 locations): resources/js/v8/views/gallery-panels/Search.vue:585 \u00B7 resources/js/v8/views/gallery-panels/Timeline.vue:624 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Search.vue"},"region":{"startLine":585}}}],"partialFingerprints":{"codehealthFindingId/v1":"de680be9290ca57c2258bcd02835e20e79faa514393f8895b375aa39d9862da8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (41 lines \u00D7 2 locations): resources/js/embed/api.ts:24 \u00B7 resources/js/embed/api.ts:76 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/api.ts"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b44c90dc6bdad6fde9cf94063275becfaa2b28e106c14dd84da98b63a9eda12"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (41 lines \u00D7 2 locations): resources/js/v7/components/diagnostics/ErrorsDiagnostics.vue:21 \u00B7 resources/js/v8/components/diagnostics/ErrorsDiagnostics.vue:23 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/diagnostics/ErrorsDiagnostics.vue"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"39b497c38c5d399f6501c8cc480d95f8b348812ad2c4edf158659031fc894eda"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (41 lines \u00D7 2 locations): resources/js/v7/components/gallery/photoModule/NsfwDetectionOverlay.vue:40 \u00B7 resources/js/v8/components/gallery/photoModule/NsfwDetectionOverlay.vue:40 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/NsfwDetectionOverlay.vue"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"a45f33dc728d9a933238a59571b55e93499287c6c49e13a4e07f506e98e918cb"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (41 lines \u00D7 2 locations): resources/js/v7/views/admin/ContactMessages.vue:166 \u00B7 resources/js/v8/views/admin/ContactMessages.vue:170 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/ContactMessages.vue"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"391bb34099c074375daed8c2eebd02c7a18740712ba75e3d16163fc9d7940d72"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (40 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/PhotoThumbPanel.vue:103 \u00B7 resources/js/v8/components/gallery/albumModule/PhotoThumbPanel.vue:70 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanel.vue"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5bc938d4467f3ad7f605d088742e7866073af00e86769828404bcd87a3df1f9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (40 matched lines \u00D7 2 locations): resources/js/v7/components/gallery/photoModule/FaceOverlay.vue:61 \u00B7 resources/js/v8/components/gallery/photoModule/FaceOverlay.vue:53 \u2014 the two spans are one implementation copied and then locally edited \u2014 259 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/FaceOverlay.vue"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"e29807eab91975f0096c2929416928dd71f344888b409dd21fd1d3820de20ee9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (40 lines \u00D7 2 locations): resources/js/v7/components/settings/CssJs.vue:25 \u00B7 resources/js/v8/components/settings/CssJs.vue:27 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/CssJs.vue"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c4bbc88435c4294aa784b2f3680c76b4599b54b8b355cbada48392a0d4e233f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (40 lines \u00D7 2 locations): resources/js/v8/views/admin/LandingConfig.vue:1011 \u00B7 resources/js/v8/views/admin/LandingConfig.vue:1144 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/LandingConfig.vue"},"region":{"startLine":1011}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e25c2c2d5f0c4b7516e463f56a5b8d306791297d9e4855e9e4c48ed22c5518f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (39 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/PhotoThumbPanelControl.vue:70 \u00B7 resources/js/v8/components/gallery/albumModule/PhotoThumbPanelControl.vue:72 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"e55257d1db15f2728569d1a4ea1484278b5b8493ef9e74b8c4bc9faf260091f1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (39 lines \u00D7 2 locations): resources/js/v7/components/maintenance/MaintenanceBulkScanFaces.vue:38 \u00B7 resources/js/v8/components/maintenance/MaintenanceBulkScanFaces.vue:23 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceBulkScanFaces.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ac8c5f7eec397a1b5ed731928271635dec52b156a1dce9e6b1ce227498f1856"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (39 matched lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Map.vue:238 \u00B7 resources/js/v8/views/gallery-panels/Map.vue:673 \u2014 the two spans are one implementation copied and then locally edited \u2014 244 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Map.vue"},"region":{"startLine":238}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5d89d8586ab44d3aee47e0d7aa5d648424e9b98237713c306b81a2967da7416"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (38 lines \u00D7 2 locations): resources/js/v7/components/maintenance/DuplicateLine.vue:57 \u00B7 resources/js/v8/components/maintenance/DuplicateLine.vue:51 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/DuplicateLine.vue"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef4113a55132c637e694f751eb58fe23d90e3874f2b325e888ae1f6d2d5d306c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (38 lines \u00D7 2 locations): resources/js/v7/components/maintenance/MaintenanceSyncFaceEmbeddings.vue:38 \u00B7 resources/js/v8/components/maintenance/MaintenanceSyncFaceEmbeddings.vue:23 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceSyncFaceEmbeddings.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f24c21e018096cf43be096056d0997d7634367a020ccd51c87f1c01e26fb467"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (38 lines \u00D7 2 locations): resources/js/v7/components/modals/KeybindingsHelp.vue:70 \u00B7 resources/js/v8/components/modals/KeybindingsHelp.vue:69 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/KeybindingsHelp.vue"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f4021672e65b9cc7e5ad4c7ba39a7fbd8b7adde9ba9b00ee2b6cafe17a3473c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (38 lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Map.vue:187 \u00B7 resources/js/v8/views/gallery-panels/Map.vue:626 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Map.vue"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b8c56efc96939a825dd0d5b7bec9602f236185ae1c9d76f0aeb24a9e5f9d81c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (37 lines \u00D7 2 locations): resources/js/v7/components/drawers/AlbumStatistics.vue:40 \u00B7 resources/js/v8/components/drawers/AlbumStatistics.vue:36 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/AlbumStatistics.vue"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"2866554472134912f3e67017db5a8597ee6ce7e4c23185e8c1b1633c000e95b8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (37 lines \u00D7 2 locations): resources/js/v7/components/headers/AlbumsHeader.vue:313 \u00B7 resources/js/v7/components/headers/TimelineHeader.vue:249 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of DECLARATIONS inside a construct \u2014 the members of a type, or the entries of an object or array literal \u2014 with no statement anywhere in it. Do not read this as an extract-a-helper row: nothing here executes, so there is no call site, and a call expression cannot stand where a member declaration or a literal\u0027s entry was. What repeats is a SHAPE, and which shape decides the move. Where the copies declare the same members, the repetition is a missing common ancestor: give it a base type, an interface both extend, a generic instantiated twice, or \u2014 where the copies are a literal\u0027s entries rather than a type\u0027s members \u2014 one shared constant each site spreads or refers to, so the set is written once. Where they declare DIFFERENT members and only the form is shared \u2014 a decorator and its options, an annotation, a registration table\u0027s keys \u2014 the form is prescribed by a framework or a schema rather than copied, and the only collapse available is to generate the declarations from that schema; where you do not own the generator, this is the cost of the framework and there is nothing to extract. Check which of the two it is before acting: these copies still drift apart the first time only one of them is edited, which is why the repetition is reported, but the sentence to act on is not the same in both cases."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/AlbumsHeader.vue"},"region":{"startLine":313}}}],"partialFingerprints":{"codehealthFindingId/v1":"a414ba1a71b3eb36b33c7b8033face26a61b839a86bdf8fdf285b1cb6a285809"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (36 lines \u00D7 2 locations): resources/js/composables/contextMenus/leftMenu.ts:28 \u00B7 resources/js/v8/composables/contextMenus/leftMenu.ts:46 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"59c9865f8e0d19e2866cec50165198832f6d0bfa605dd1b243ff4483b522206d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (36 lines \u00D7 2 locations): resources/js/v7/views/BulkAlbumEdit.vue:416 \u00B7 resources/js/v8/views/BulkAlbumEdit.vue:511 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":416}}}],"partialFingerprints":{"codehealthFindingId/v1":"ddf4639e8cd611cb86f06d33b099222ef45f34882b8d13653af092139de3b16e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (36 lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Frame.vue:47 \u00B7 resources/js/v8/views/gallery-panels/Frame.vue:56 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Frame.vue"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"be4078366a9753107ce27f2e21a037fc88d3a3075e0ba51c0e032d17c2d56574"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (35 matched lines \u00D7 2 locations): resources/js/v7/components/forms/album/AlbumDelete.vue:28 \u00B7 resources/js/v8/components/forms/album/AlbumDelete.vue:29 \u2014 the two spans are one implementation copied and then locally edited \u2014 222 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumDelete.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"1efd3b7c955e47c4b102b9200f26abaa4dfd1be02f2b41a64ceb207646462e90"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2 locations): resources/js/v7/components/forms/profile/SetOauth.vue:33 \u00B7 resources/js/v8/components/forms/profile/SetOauth.vue:29 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetOauth.vue"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0c6fe6e5f55c6d23386d6aa691106f6f974537ddd1de2bf7adcab0b8dbdf6a9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 4 locations): resources/js/v7/components/maintenance/MaintenanceBackfillAlbumSizes.vue:38 \u00B7 resources/js/v7/components/maintenance/MaintenanceFulfillPrecompute.vue:38 \u00B7 resources/js/v8/components/maintenance/MaintenanceBackfillAlbumSizes.vue:23 \u00B7 resources/js/v8/components/maintenance/MaintenanceFulfillPrecompute.vue:23 \u2014 the 4 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 4 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceBackfillAlbumSizes.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d20cfda214ded26b1b01b41d68bf2a5ef05e0f8646f26f4b6bda2db17ca7aa2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2 locations): resources/js/v7/components/modals/ShareAlbum.vue:39 \u00B7 resources/js/v8/components/modals/ShareAlbum.vue:40 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/ShareAlbum.vue"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"96eed463c5c2221174df7260292f75c8b27a5601052c5439186953e7884bca31"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (35 matched lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Favourites.vue:55 \u00B7 resources/js/v8/views/gallery-panels/Favourites.vue:53 \u2014 the two spans are one implementation copied and then locally edited \u2014 294 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Favourites.vue"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"8fe993ebde6e4fd64ee2420e5714df3ddd4735b872a9b48748df12046be7ab22"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2 locations): resources/js/v7/views/webshop/CheckoutPage.vue:235 \u00B7 resources/js/v8/views/webshop/CheckoutPage.vue:204 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/CheckoutPage.vue"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7a85f3bee29b18514860f1177aa15ef824fcca12e1846daa124e92ab836c3cc"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2 locations): resources/js/v7/components/forms/profile/SetSecondFactorLine.vue:27 \u00B7 resources/js/v8/components/forms/profile/SetSecondFactorLine.vue:21 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetSecondFactorLine.vue"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"d592da22547024c81b74047063a5a897638805b9d84a48cde7b3ab930529c049"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2 locations): resources/js/v7/components/forms/shop-management/PricesInput.vue:55 \u00B7 resources/js/v8/components/forms/shop-management/PricesInput.vue:62 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PricesInput.vue"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"08dc5cb080ed2038f6b59839c453b8ec546dedd95b69880142b1d8d2fc0f9ab2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/AlbumTagFilter.vue:86 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumTagFilter.vue:82 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumTagFilter.vue"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a3270de5f18bf0d3df1c925674ee886ff2a835469ccea2b39c15cd37b7fefda"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2 locations): resources/js/v7/components/gallery/photoModule/PhotoBox.vue:174 \u00B7 resources/js/v8/components/gallery/photoModule/PhotoBox.vue:508 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoBox.vue"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5371daa8df1ba920a75effdc522137a9cbdcd989718daa5d5d62a484de324dc"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2 locations): resources/js/v8/components/headers/AlbumsHeader.vue:162 \u00B7 resources/js/v8/components/headers/TimelineHeader.vue:120 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/AlbumsHeader.vue"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"4113a1524cefb60f2302dd1eecea2a091e68df6685bb0b38536b28c1271ec4b7"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2 locations): resources/js/v7/components/forms/album/AlbumMove.vue:34 \u00B7 resources/js/v8/components/forms/album/AlbumMove.vue:40 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumMove.vue"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"779ab789839ece38ef59caa30218cddc7b17e004e756602fc13c038de78d6756"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2 locations): resources/js/v7/components/forms/album/SearchTargetUser.vue:52 \u00B7 resources/js/v8/components/forms/album/SearchTargetUser.vue:48 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/SearchTargetUser.vue"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"77b37ba9955f31a61dbe2fca1822304958962ca898a6fbb09adbed14810cb2a6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2 locations): resources/js/v7/components/modals/faceRecog/MergePersonModal.vue:98 \u00B7 resources/js/v8/components/modals/faceRecog/MergePersonModal.vue:105 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/faceRecog/MergePersonModal.vue"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"168fd8b6b8b0ac00856436a49ac0873a032fe08fecd498c1f58ff10e5982dff3"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2 locations): resources/js/v8/components/gallery/tagModule/TagPanel.vue:135 \u00B7 resources/js/v8/views/gallery-panels/Albums.vue:384 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/tagModule/TagPanel.vue"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"44449e04e3e3b9e5865e8a662447f2f9e365e4e64eff9c930a413af294b75655"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2 locations): resources/js/v8/composables/contextMenus/contextMenuAlbumAdd.ts:25 \u00B7 resources/js/v8/composables/contextMenus/contextMenuAlbumsAdd.ts:20 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/contextMenuAlbumAdd.ts"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca0ad9320a40c7a0919906d0a32fbf29e3b219688f5be869a2a91b0b23e3b6aa"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (32 matched lines \u00D7 2 locations): resources/js/v7/components/forms/album/SearchTargetAlbum.vue:32 \u00B7 resources/js/v8/components/forms/album/SearchTargetAlbum.vue:40 \u2014 the two spans are one implementation copied and then locally edited \u2014 198 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/SearchTargetAlbum.vue"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"aeb30262e391a7c94581524ca3352553f2e5ae7af97ee7364507cb031b7db085"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2 locations): resources/js/composables/contextMenus/contextMenuAlbumAdd.ts:4 \u00B7 resources/js/v8/composables/contextMenus/contextMenuAlbumAdd.ts:4 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenuAlbumAdd.ts"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"212195eb96e3208e541ee222fcf1b46b1180ef632fa591add8615681e24c71ab"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2 locations): resources/js/layouts/useGrid.ts:7 \u00B7 resources/js/layouts/useSquare.ts:6 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/useGrid.ts"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"8279eb508b3ba6f9112682143c537a6ad920d64a3eeb4d10c65ce5759633a059"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2 locations): resources/js/v7/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue:266 \u00B7 resources/js/v8/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue:318 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1228adacfcfe9c3c74b9b7dc2a71d80f6344addbc338ebef449e838521332c6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2 locations): resources/js/v7/components/forms/bulk-album-edit/BulkSetOwnerDialog.vue:46 \u00B7 resources/js/v8/components/forms/bulk-album-edit/BulkSetOwnerDialog.vue:49 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/bulk-album-edit/BulkSetOwnerDialog.vue"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"76e6239d3cedd380c84745f309c7525525ebdd9492fd90687b9aa616ceaace41"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2 locations): resources/js/v7/components/forms/profile/ApiToken.vue:62 \u00B7 resources/js/v8/components/forms/profile/ApiToken.vue:39 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/ApiToken.vue"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"e60bd574569c4c92e327ececcefd325f6a3b1cbffee7f52efded4d84fe3174f8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2 locations): resources/js/v7/components/forms/settings/PasswordField.vue:46 \u00B7 resources/js/v8/components/forms/settings/PasswordField.vue:36 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/PasswordField.vue"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"338ae94533a55dfdf121ba630df3a2c64c05f497aca353625a19f7a91c0bd4ef"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2 locations): resources/js/v7/components/gallery/photoModule/PhotoRatingOverlay.vue:47 \u00B7 resources/js/v8/components/gallery/photoModule/PhotoRatingOverlay.vue:55 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoRatingOverlay.vue"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"95eae5a88fea98df2bd67c8935d6dbd20975cc32dabb631669d87eba6447a871"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2 locations): resources/js/v7/components/gallery/timelineModule/TimelineDates.vue:52 \u00B7 resources/js/v8/components/gallery/timelineModule/TimelineDates.vue:52 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/timelineModule/TimelineDates.vue"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9beb9074c7a44fdaf10c056e5373fc6e51cbf6b1d52c1e660fa7de7d0a514cd"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2 locations): resources/js/v7/components/maintenance/MaintenanceCleaning.vue:38 \u00B7 resources/js/v8/components/maintenance/MaintenanceCleaning.vue:21 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceCleaning.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"dff9a343c267d387455ab38aeaa5b5ce838f5426a1095b1d82cbae87d7bdd128"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2 locations): resources/js/v8/components/headers/AlbumsHeader.vue:300 \u00B7 resources/js/v8/components/headers/TimelineHeader.vue:227 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of DECLARATIONS inside a construct \u2014 the members of a type, or the entries of an object or array literal \u2014 with no statement anywhere in it. Do not read this as an extract-a-helper row: nothing here executes, so there is no call site, and a call expression cannot stand where a member declaration or a literal\u0027s entry was. What repeats is a SHAPE, and which shape decides the move. Where the copies declare the same members, the repetition is a missing common ancestor: give it a base type, an interface both extend, a generic instantiated twice, or \u2014 where the copies are a literal\u0027s entries rather than a type\u0027s members \u2014 one shared constant each site spreads or refers to, so the set is written once. Where they declare DIFFERENT members and only the form is shared \u2014 a decorator and its options, an annotation, a registration table\u0027s keys \u2014 the form is prescribed by a framework or a schema rather than copied, and the only collapse available is to generate the declarations from that schema; where you do not own the generator, this is the cost of the framework and there is nothing to extract. Check which of the two it is before acting: these copies still drift apart the first time only one of them is edited, which is why the repetition is reported, but the sentence to act on is not the same in both cases."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/AlbumsHeader.vue"},"region":{"startLine":300}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbcdf98c1064959dd5375d189f9509d39d83563df939d545a12707f097ae422c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (30 lines \u00D7 2 locations): resources/js/v7/views/Diagnostics.vue:43 \u00B7 resources/js/v8/views/Diagnostics.vue:33 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Diagnostics.vue"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b8056157dd1dd3647304de672dbc286c175eeaadd7c9468fb60d2b3b4b18e02"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 2 locations): resources/js/v7/components/headers/TimelineHeader.vue:130 \u00B7 resources/js/v8/components/headers/TimelineHeader.vue:88 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/TimelineHeader.vue"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc2e6f4af90d10414df27414a82691ead86c655f540d3d647fdb270d3723da91"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 7 locations): resources/js/v7/components/maintenance/MaintenanceBulkScanFaces.vue:36 \u00B7 resources/js/v7/components/maintenance/MaintenanceDestroyDismissedFaces.vue:36 \u00B7 resources/js/v7/components/maintenance/MaintenanceResetFaceScanStatus.vue:36 \u00B7 resources/js/v8/components/maintenance/MaintenanceBulkScanFaces.vue:21 \u00B7 \u002B3 more site(s) not listed \u2014 the 7 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 7 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceBulkScanFaces.vue"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"9191700dfa9c26ac4313a963678a5c5d31144d797534fa8dff368bd4d20f7228"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 2 locations): resources/js/v7/components/maintenance/StatisticsIntegrity.vue:41 \u00B7 resources/js/v8/components/maintenance/StatisticsIntegrity.vue:26 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/StatisticsIntegrity.vue"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"84b05a03e7af3059ce6e21275011d8f65330b4de996a4478278c08ead55943bc"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 2 locations): resources/js/v7/views/admin/NsfwConfig.vue:423 \u00B7 resources/js/v8/views/admin/NsfwConfig.vue:386 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":423}}}],"partialFingerprints":{"codehealthFindingId/v1":"82018b3fe965053be9782c8d1ad37afe5f0be15e1147d05420caf924485ee6ab"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 3 locations): resources/js/embed/layouts/grid.ts:25 \u00B7 resources/js/embed/layouts/justified.ts:25 \u00B7 resources/js/embed/layouts/masonry.ts:24 \u2014 the 3 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it. There is one copy in each of 3 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/layouts/grid.ts"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f112fe99fa789b296c0dec02f7fce0ef040d9f82f4ab3e25a4f7eefa917d822"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2 locations): resources/js/v7/components/forms/shop-management/PixelSizePricesInput.vue:50 \u00B7 resources/js/v8/components/forms/shop-management/PixelSizePricesInput.vue:57 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PixelSizePricesInput.vue"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e35fc9162d89967cfa6ef2eef8d91eada6c64895f00fac5e08f2b3009f80c4d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2 locations): resources/js/v7/components/forms/tags/TagRenameDialog.vue:34 \u00B7 resources/js/v8/components/forms/tags/TagRenameDialog.vue:36 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/tags/TagRenameDialog.vue"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a542fc33de7fc944640e6e680a1cc5ad926cc58a26e36f12d652f41a2dcf050"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2 locations): resources/js/v7/components/headers/AlbumsHeader.vue:162 \u00B7 resources/js/v8/components/headers/AlbumsHeader.vue:129 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/AlbumsHeader.vue"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3b9e0c4cc0da34e15306327a2128784ed3d3635a507135880ec0d05b2079ae7"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2 locations): resources/js/v7/components/headers/AlbumsHeader.vue:240 \u00B7 resources/js/v7/components/headers/TimelineHeader.vue:199 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/AlbumsHeader.vue"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"2cbf5d029f001fbb1091d49c496a061ad4ed324870543482565c653b86826f80"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2 locations): resources/js/v7/views/BulkAlbumEdit.vue:467 \u00B7 resources/js/v8/views/BulkAlbumEdit.vue:555 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":467}}}],"partialFingerprints":{"codehealthFindingId/v1":"b489c7afbb3d0ca42b235089b129614a1572ee5e25ac8de2f5dad5069451191a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2 locations): resources/js/v8/components/gallery/albumModule/AlbumPanel.vue:675 \u00B7 resources/js/v8/components/gallery/searchModule/ResultPanel.vue:156 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumPanel.vue"},"region":{"startLine":675}}}],"partialFingerprints":{"codehealthFindingId/v1":"4353ca87dbac1d4f613d30077e88d0ae49a503653170ec5546e66b334418aa03"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 3 locations): resources/js/v8/components/landing/LandingBackgroundField.vue:82 \u00B7 resources/js/v8/views/admin/WatermarkPreview.vue:420 \u00B7 resources/js/v8/views/admin/WatermarkPreview.vue:450 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/landing/LandingBackgroundField.vue"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"4bba2e216f189e659b91c2700bf561a7097516dbe92e67f24f51e5f874bcd31f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2 locations): resources/js/composables/contextMenus/contextMenuAlbumsAdd.ts:4 \u00B7 resources/js/v8/composables/contextMenus/contextMenuAlbumsAdd.ts:4 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenuAlbumsAdd.ts"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"577407979ae0483e612506160695186457af9264d7aba19a5f0f07b865b4074d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (27 matched lines \u00D7 2 locations): resources/js/stores/AlbumState.ts:439 \u00B7 resources/js/stores/TimelineState.ts:390 \u2014 the two spans are one implementation copied and then locally edited \u2014 252 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumState.ts"},"region":{"startLine":439}}}],"partialFingerprints":{"codehealthFindingId/v1":"81d605c0a76d7369f1b04505a008763fdd8516e8fd5abc27e277eb177a922300"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (27 matched lines \u00D7 2 locations): resources/js/v7/components/forms/album/AlbumVisibility.vue:150 \u00B7 resources/js/v8/components/forms/album/AlbumVisibility.vue:114 \u2014 the two spans are one implementation copied and then locally edited \u2014 317 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumVisibility.vue"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"c25fcec2772f3b6ad6941355347af3b1afea022819e926406a8b1c9a701e4062"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2 locations): resources/js/v7/components/forms/settings/BoolField.vue:28 \u00B7 resources/js/v8/components/forms/settings/BoolField.vue:27 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/BoolField.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4c911ff82d876b407d75265db2c15f25d1fea9de7d363b83b56cb57d36449fd"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2 locations): resources/js/v7/components/forms/settings/SelectLang.vue:18 \u00B7 resources/js/v8/components/forms/settings/SelectLang.vue:23 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SelectLang.vue"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bfd0f3555c3daaff17e8339058c6488645ee14cc88cac36bef9ec3622de8cde"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2 locations): resources/js/v7/components/forms/shop-management/PrintSizeFormDialog.vue:88 \u00B7 resources/js/v8/components/forms/shop-management/PrintSizeFormDialog.vue:71 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PrintSizeFormDialog.vue"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f0d24d75bb03fa37e7c031aaead053874ece8418d82adaa14e07530029decdf"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumbOverlay.vue:44 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/AlbumThumbOverlay.vue:47 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumbOverlay.vue"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"612c4693de780081aa6b427dee4efadcaff290d61a65799619b73bcc8d7fe197"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2 locations): resources/js/v7/components/gallery/flowModule/AlbumCard.vue:99 \u00B7 resources/js/v8/components/gallery/flowModule/AlbumCard.vue:103 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/AlbumCard.vue"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"973163c97dc6572a68a888f0a8f2c1c5589d56f1d549a413e970463debf5f44d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (27 matched lines \u00D7 2 locations): resources/js/v7/components/headers/PhotoHeader.vue:94 \u00B7 resources/js/v8/components/headers/PhotoHeader.vue:148 \u2014 the two spans are one implementation copied and then locally edited \u2014 178 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/PhotoHeader.vue"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"2cff4c52fbefa6c9261dbf7d576065f6ec4c80e26dbf20525f6fd70e91897065"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 10 locations): resources/js/v7/components/maintenance/MaintenanceFilesize.vue:38 \u00B7 resources/js/v7/components/maintenance/MaintenanceFlushQueue.vue:38 \u00B7 resources/js/v7/components/maintenance/MaintenanceFulfillOrders.vue:38 \u00B7 resources/js/v7/components/maintenance/MaintenanceMissingPalettes.vue:38 \u00B7 \u002B6 more site(s) not listed \u2014 the 10 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 10 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFilesize.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"469f2de2d653bae4f3571fa37d696f761c0ca582cdf03776d8fe872096ba544f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 3 locations): resources/js/v7/components/maintenance/MaintenancePurgeOrphanFaceEmbeddings.vue:38 \u00B7 resources/js/v7/components/maintenance/MaintenanceSyncFaceEmbeddings.vue:38 \u00B7 resources/js/v8/components/maintenance/MaintenanceSyncFaceEmbeddings.vue:23 \u2014 the 3 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 3 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenancePurgeOrphanFaceEmbeddings.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"73595df1d981809a973aad377ced8f844733ede14a6089abdaa9fbd657a7d422"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (27 matched lines \u00D7 2 locations): resources/js/v7/components/modals/faceRecog/BatchFaceAssignmentModal.vue:60 \u00B7 resources/js/v8/components/modals/faceRecog/BatchFaceAssignmentModal.vue:65 \u2014 the two spans are one implementation copied and then locally edited \u2014 294 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/faceRecog/BatchFaceAssignmentModal.vue"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"a48f2b658c6feafd66bb74aea7cedf692e4c6588a294ae50461f60123bb5a39f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2 locations): resources/js/v7/components/statistics/AlbumsTable.vue:47 \u00B7 resources/js/v8/components/statistics/AlbumsTable.vue:55 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/statistics/AlbumsTable.vue"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebefcb15754427ac22c0c7bc4d83d98106959e1040d815bb2195cdb0d9de4040"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2 locations): resources/js/v7/menus/LeftMenu.vue:172 \u00B7 resources/js/v8/menus/LeftMenu.vue:167 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/menus/LeftMenu.vue"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"b07179546d09b1a9d7e75fbe93d8020db9b75e8c34158ecbbf3f48350e768d9c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2 locations): resources/js/v7/components/forms/shop-management/PixelSizeFormDialog.vue:66 \u00B7 resources/js/v8/components/forms/shop-management/PixelSizeFormDialog.vue:52 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PixelSizeFormDialog.vue"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cfa7b170b61d340f195ad18617f0971ed64d72c7e1029b014f6b75d901f0e99"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2 locations): resources/js/v7/components/forms/tags/TagMergeDialog.vue:32 \u00B7 resources/js/v8/components/forms/tags/TagMergeDialog.vue:39 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/tags/TagMergeDialog.vue"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"776786f590afd87cd35691543aa4e1bc5eec342a31db8f99da949208665dd0ed"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumbDecorations.vue:22 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/AlbumThumbDecorations.vue:22 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumbDecorations.vue"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e1972a6b7a2755329f68ac2fa1fe7ced74516d407b65900a84d97e2fab84bd8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2 locations): resources/js/v7/components/gallery/photoModule/LinksInclude.vue:29 \u00B7 resources/js/v8/components/gallery/photoModule/LinksInclude.vue:28 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/LinksInclude.vue"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b68c8de521015a04521b48ea615cd5b0fae720b5ac79eb3ee2decf26424fe81"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (26 matched lines \u00D7 2 locations): resources/js/v8/components/drawers/PhotoEdit.vue:116 \u00B7 resources/js/v8/components/forms/album/AlbumProperties.vue:264 \u2014 the two spans are one implementation copied and then locally edited \u2014 294 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoEdit.vue"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"781b4f3b59ba30e64f0208f4ca64076a67f9b7ca1947cc2ec7e6690f76c5e27c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (26 matched lines \u00D7 2 locations): resources/js/v8/composables/usePanZoom.ts:344 \u00B7 resources/js/v8/composables/useSphereViewer.ts:464 \u2014 the two spans are one implementation copied and then locally edited \u2014 157 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/usePanZoom.ts"},"region":{"startLine":344}}}],"partialFingerprints":{"codehealthFindingId/v1":"6776df7b94e78c49997022806f28ce432fa952408ecef76993501943dbe566f2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 4 locations): resources/js/v8/views/gallery-panels/Album.vue:416 \u00B7 resources/js/v8/views/gallery-panels/Search.vue:596 \u00B7 resources/js/v8/views/gallery-panels/Tag.vue:237 \u00B7 resources/js/v8/views/gallery-panels/Timeline.vue:635 \u2014 the 4 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it. There is one copy in each of 4 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Album.vue"},"region":{"startLine":416}}}],"partialFingerprints":{"codehealthFindingId/v1":"65c49067efdc6adb3a82952de3082d3a06222057e32b48eb7c4521f43c7fc04c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (25 matched lines \u00D7 2 locations): resources/js/stores/PhotosState.ts:112 \u00B7 resources/js/stores/PhotosState.ts:166 \u2014 the two spans are one implementation copied and then locally edited \u2014 204 tokens are still identical, in the same order in both spans, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/PhotosState.ts"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"9188bf9a6ae6616fe7a7b41ac4edc0812f4b426e3efa93d6aaac42742f71ffd2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2 locations): resources/js/v7/components/forms/album/WatermarkConfirmDialog.vue:26 \u00B7 resources/js/v8/components/forms/album/WatermarkConfirmDialog.vue:24 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/WatermarkConfirmDialog.vue"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"38642927ef1d4969c96e81a3249ca743d0d617031e5c8190cd39082df772a67e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2 locations): resources/js/v7/components/forms/profile/SetSecondFactor.vue:28 \u00B7 resources/js/v8/components/forms/profile/SetSecondFactor.vue:27 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetSecondFactor.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc161171e2b94a472d76d34f4e4f9553affb2052e25729a2a5d9a7fdc3466c0d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2 locations): resources/js/v7/components/forms/settings/SelectOptionsField.vue:51 \u00B7 resources/js/v8/components/forms/settings/SelectOptionsField.vue:49 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SelectOptionsField.vue"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d06b3dcb79f4f50995d39e8f67017ca9b12231ce3e6f713b8b320460dcaad71"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2 locations): resources/js/v7/components/forms/webhooks/WebhookFormDialog.vue:133 \u00B7 resources/js/v8/components/forms/webhooks/WebhookFormDialog.vue:104 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/webhooks/WebhookFormDialog.vue"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"4eb52e3d17a90b153cdb133baf65678d11cd956c12b281697b1cd562196b44b8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2 locations): resources/js/v7/components/modals/RegisterLychee.vue:71 \u00B7 resources/js/v8/components/modals/RegisterLychee.vue:61 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/RegisterLychee.vue"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd1258328149d4fb1eac38506ae59f6ec633066078d58b737b12db0b5b0dc351"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Map.vue:44 \u00B7 resources/js/v8/views/gallery-panels/Map.vue:48 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Map.vue"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4bea4ddf114f2ed2717bf9e1687e210d4260a98235dec7c14e80ffd91c2faa8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2 locations): resources/js/services/landing-link-service.ts:16 \u00B7 resources/js/services/webhook-service.ts:23 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/landing-link-service.ts"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"02aa5245696da494eb630aa11553d4e81d8af43be340a11b5417c4fb882c348a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2 locations): resources/js/v7/components/forms/basic/rating.vue:29 \u00B7 resources/js/v8/components/forms/basic/rating.vue:32 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/rating.vue"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab2e5be007c5378e6dc79d32f1d73b24fca1f50407cfb6ad4421c0ccbe2d27b1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2 locations): resources/js/v7/components/forms/settings/SelectField.vue:25 \u00B7 resources/js/v8/components/forms/settings/SelectField.vue:30 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SelectField.vue"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4d59ab423b0a3be43bc3eabc450e87133c45e92b4cb74eef70508aa846943e6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2 locations): resources/js/v7/components/forms/settings/SliderField.vue:30 \u00B7 resources/js/v8/components/forms/settings/SliderField.vue:43 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SliderField.vue"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9c784284d0daa029609245f385b20c5d997b350c7628051fa630dcc1b83b7b3"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumb.vue:99 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/AlbumThumb.vue:114 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumb.vue"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"415dec1d97ab5103a950343f566cd82af2c79bf4e576cbb1a74c333c353593ad"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2 locations): resources/js/v7/components/modals/WebauthnModal.vue:52 \u00B7 resources/js/v8/components/modals/WebauthnModal.vue:43 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/WebauthnModal.vue"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"249c9af7053250e7cfc74dbc02036e37b0d4ba34c0dfeaae17ed3ddf4c90e0dc"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (24 matched lines \u00D7 2 locations): resources/js/v7/components/settings/AllSettings.vue:38 \u00B7 resources/js/v8/components/settings/AllSettings.vue:33 \u2014 the two spans are one implementation copied and then locally edited \u2014 156 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/AllSettings.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"39d4cc870ca67f5fd0c7d6de0ae295fb70ca1e5bad09189f4784b59b81b54797"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2 locations): resources/js/v7/views/BulkAlbumEdit.vue:356 \u00B7 resources/js/v8/views/BulkAlbumEdit.vue:318 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":356}}}],"partialFingerprints":{"codehealthFindingId/v1":"5da51b46d449411be8f441a6762e5adb200cd7159b072e8bbea55eb2f60d51c2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2 locations): resources/js/v7/views/admin/NsfwConfig.vue:340 \u00B7 resources/js/v8/views/admin/NsfwConfig.vue:299 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":340}}}],"partialFingerprints":{"codehealthFindingId/v1":"5acad87d16de6843a2374c6e79e580e13223848eccc9724d155e1b7ff292eadd"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2 locations): resources/js/v7/views/admin/Users.vue:116 \u00B7 resources/js/v8/views/admin/Users.vue:251 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Users.vue"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7b1487e0f8694259b60a69586a255bae0370d9feb4e3a9572c98483c3c39588"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2 locations): resources/js/v8/components/forms/gallery-dialogs/AlbumMergeDialog.vue:100 \u00B7 resources/js/v8/components/forms/gallery-dialogs/MoveDialog.vue:147 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/gallery-dialogs/AlbumMergeDialog.vue"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8c720b8d1bc08c615aaeded52b0094c402572464709c84db043e97ad4c725d7"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2 locations): resources/js/v8/components/forms/settings/OldField.vue:31 \u00B7 resources/js/v8/components/forms/settings/StringField.vue:29 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/OldField.vue"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0b14170ad7a0d269992c5cf0ec09a0a52154f1234479cc0496bfa620449a342"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (23 matched lines \u00D7 2 locations): resources/js/composables/photo/slideshow.ts:45 \u00B7 resources/js/composables/photo/slideshow.ts:120 \u2014 the two spans are one implementation copied and then locally edited \u2014 134 tokens are still identical, in the same order in both spans, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/photo/slideshow.ts"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac3df44067cf988f313812f1960896979443c431071ce382eb823a3b850e7250"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2 locations): resources/js/services/landing-featured-item-service.ts:14 \u00B7 resources/js/services/landing-link-service.ts:20 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/landing-featured-item-service.ts"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0886363b02d88f67defc895a1da22d8ded9659cc159db48e5fd80d07ae566cb"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2 locations): resources/js/utils/StatsSizeVariantToColours.ts:2 \u00B7 resources/js/v8/composables/useSizeVariantStats.ts:8 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/utils/StatsSizeVariantToColours.ts"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"c80e29542fbbf5d654cf616e40dcf3c85b651f9ad132e9d18feff897d5196402"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2 locations): resources/js/v7/components/forms/photo/PhotoLicenseDialog.vue:70 \u00B7 resources/js/v8/components/forms/photo/PhotoLicenseDialog.vue:76 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/photo/PhotoLicenseDialog.vue"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf057eedf0aaaa2d48b10d1772371f0e141eacb9c79d39cf29859def339c218f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2 locations): resources/js/v7/components/forms/settings/NumberField.vue:35 \u00B7 resources/js/v8/components/forms/settings/NumberField.vue:29 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/NumberField.vue"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"c143831bd3a99041c546f1a989e4acf84436c77c8f56d88282b4cbc9b888c6a0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2 locations): resources/js/v7/components/gallery/photoModule/PhotoBox.vue:131 \u00B7 resources/js/v8/components/gallery/photoModule/PhotoBox.vue:192 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoBox.vue"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"66eaf2b47297992ab6896ace80358b6739c2d5b1fb935e4285fc69a627528a71"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2 locations): resources/js/v7/components/statistics/SizeVariantMeter.vue:39 \u00B7 resources/js/v8/components/statistics/SizeVariantMeter.vue:41 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/statistics/SizeVariantMeter.vue"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8e86185fc14868b103b47cb517206b46533b5a958c79b579ec6144f5fe12bf6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2 locations): resources/js/v7/components/webshop/InfoSection.vue:99 \u00B7 resources/js/v8/components/webshop/InfoSection.vue:92 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/InfoSection.vue"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"74cc9440582b41c6979ac0ad616cea3cd308865e82478b6d59f043dabc187069"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2 locations): resources/js/v7/components/forms/settings/ZipSliderField.vue:23 \u00B7 resources/js/v8/components/forms/settings/ZipSliderField.vue:30 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/ZipSliderField.vue"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"145d1a7518c150fef242f683a44f05c04224651637d6fa6498108eb92422f2a0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2 locations): resources/js/v7/components/modals/SecurityAdvisoriesModal.vue:72 \u00B7 resources/js/v8/components/modals/SecurityAdvisoriesModal.vue:53 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/SecurityAdvisoriesModal.vue"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"ecbf2ae2caf31c2adacdab68eee51013deaa5d7107c3a294115cd9654fcdf8ee"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2 locations): resources/js/v7/components/modals/faceRecog/FaceAssignmentModal.vue:108 \u00B7 resources/js/v8/components/modals/faceRecog/FaceAssignmentModal.vue:122 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/faceRecog/FaceAssignmentModal.vue"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"02d05ea46da1d959d311d5cbc49666b36f98319a900fd4384fe4ead09b18b3fa"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2 locations): resources/js/v7/components/webshop/PaymentForm.vue:57 \u00B7 resources/js/v8/components/webshop/PaymentForm.vue:56 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/PaymentForm.vue"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"876256d0fa1e65678683f64aea6d896e4f2ff55afb91bd635216173ffcd6f155"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2 locations): resources/js/v7/components/webshop/QrCodeLink.vue:14 \u00B7 resources/js/v8/components/webshop/QrCodeLink.vue:14 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/QrCodeLink.vue"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"310f6e40a3c53e35444a612f3b307961ff6bd2366501a24fbd300eb062c70b0e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2 locations): resources/js/composables/album/treeOperations.ts:184 \u00B7 resources/js/composables/album/treeOperations.ts:226 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/treeOperations.ts"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"d40eacec87b075ad4cc18fe3838dc19d1425b045d5db2714fcdbb1575046e232"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2 locations): resources/js/composables/contextMenus/contextMenuAlbumsAdd.ts:64 \u00B7 resources/js/v8/composables/contextMenus/contextMenuAlbumsAdd.ts:64 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenuAlbumsAdd.ts"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"d790fdafe49a2ea85b5c42d8fc23ef88981ac81f18e99fce7c8eda8ef955cd22"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2 locations): resources/js/v7/components/forms/webhooks/WebhookDeleteDialog.vue:45 \u00B7 resources/js/v8/components/forms/webhooks/WebhookDeleteDialog.vue:52 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/webhooks/WebhookDeleteDialog.vue"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee142e4d75cb42cb5fe0648b4b5971be9242bf008c7a0d2eae8a5a48f8ab43ce"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/PhotoListView.vue:21 \u00B7 resources/js/v8/components/gallery/albumModule/PhotoListView.vue:21 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoListView.vue"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee0590246b80a32b0939889db5c0881cf0f81b766df6b6034bba968c07f4ebcb"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2 locations): resources/js/v7/components/pagination/PaginationLoadMore.vue:12 \u00B7 resources/js/v8/components/pagination/PaginationLoadMore.vue:19 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/pagination/PaginationLoadMore.vue"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2db689e367395bd23840cd33cf56386bff329cbbea2a05d06ea8c9a9b2afe04"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2 locations): resources/js/v7/components/webshop/Disclaimer.vue:22 \u00B7 resources/js/v8/components/webshop/Disclaimer.vue:21 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/Disclaimer.vue"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f32ebf394715144f4334f6931da9b85514e0d5223c5db990f6530721944d151"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2 locations): resources/js/v7/views/webshop/BasketList.vue:94 \u00B7 resources/js/v8/views/webshop/BasketList.vue:95 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/BasketList.vue"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"c71f09444323aada8001faac53b37ad73c33cc65cf0ade04dbad106d4984db0f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 3 locations): resources/js/v8/components/admin/moderation/ModerationHistoryTable.vue:105 \u00B7 resources/js/v8/views/admin/Moderation.vue:283 \u00B7 resources/js/v8/views/admin/NsfwFindings.vue:316 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/admin/moderation/ModerationHistoryTable.vue"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"564e720263b32d26c73305bae2c3509f11b37fa1f029be0b56644fadcd426617"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2 locations): resources/js/composables/contextMenus/leftMenu.ts:122 \u00B7 resources/js/v8/composables/contextMenus/leftMenu.ts:138 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"41322d52646793c3fee5aad55d3155728bc38bee1bb06e8d1a6349bc2c4fac17"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2 locations): resources/js/stores/SearchState.ts:124 \u00B7 resources/js/stores/SearchState.ts:155 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/SearchState.ts"},"region":{"startLine":124}}}],"partialFingerprints":{"codehealthFindingId/v1":"66d76c2e8130a1330a70c0f22208ae023db45d58f3ebd6a1d87756dd78cd9beb"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2 locations): resources/js/v7/components/forms/album/ConfirmSharingDialog.vue:57 \u00B7 resources/js/v8/components/forms/album/ConfirmSharingDialog.vue:60 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/ConfirmSharingDialog.vue"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"071a89222d80336d8e99cfebdf4aa3a5194cd24b0fb5339fea6fea340f1e485a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2 locations): resources/js/v7/components/forms/shop-management/PrintSizePricesInput.vue:46 \u00B7 resources/js/v8/components/forms/shop-management/PrintSizePricesInput.vue:54 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PrintSizePricesInput.vue"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"5561a58ac5fb4954dd5e5c3ed2209f7036f1d2f77a20c6ad19062529578a4bb0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2 locations): resources/js/v7/components/forms/shop-management/SizeDeleteDialog.vue:45 \u00B7 resources/js/v8/components/forms/shop-management/SizeDeleteDialog.vue:50 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/SizeDeleteDialog.vue"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd93e2aec9e58a16bba67ba40b46d0a4f1534feab295b628305ecb7dadd2b5bb"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2 locations): resources/js/v7/components/maintenance/MaintenanceFixJobs.vue:38 \u00B7 resources/js/v8/components/maintenance/MaintenanceFixJobs.vue:23 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFixJobs.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"94a41a51d29383178790f90fe3558cfe00ef403b363ef2320b5399c32c526c66"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2 locations): resources/js/v7/components/modals/DropBox.vue:29 \u00B7 resources/js/v8/components/modals/DropBox.vue:22 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/DropBox.vue"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"116c4e052153a09171c5abecc84079149787f92738f5ae3620c3956cfde67824"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Search.vue:529 \u00B7 resources/js/v7/views/gallery-panels/Tag.vue:242 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Search.vue"},"region":{"startLine":529}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef23f549ab478b18a8fb182622f1ea2d275de662b7e180f97a86e3b0f4fda807"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 4 locations): resources/js/v7/views/gallery-panels/Timeline.vue:466 \u00B7 resources/js/v8/views/gallery-panels/Search.vue:587 \u00B7 resources/js/v8/views/gallery-panels/Tag.vue:228 \u00B7 resources/js/v8/views/gallery-panels/Timeline.vue:626 \u2014 the 4 copies are spread across 4 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Timeline.vue"},"region":{"startLine":466}}}],"partialFingerprints":{"codehealthFindingId/v1":"380753cff0b749479026a8f29454b7508bbd6bbbce95228ca841370e18d8929e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 4 locations): resources/js/embed/layouts/grid.ts:35 \u00B7 resources/js/embed/layouts/justified.ts:36 \u00B7 resources/js/embed/layouts/masonry.ts:34 \u00B7 resources/js/embed/layouts/square.ts:28 \u2014 the 4 copies are spread across 4 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/layouts/grid.ts"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"887947241d320b971bd53eebbce69ef1b7c6a2e5eaab4ba41e2578d2f529b3d8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2 locations): resources/js/stores/LycheeState.ts:200 \u00B7 resources/js/stores/ShopManagement.ts:34 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/LycheeState.ts"},"region":{"startLine":200}}}],"partialFingerprints":{"codehealthFindingId/v1":"119dac56da3f735f7e00605f81b82cbd805f8103d7b9bc464933a84ace2c7990"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2 locations): resources/js/v7/components/forms/album/AlbumCreatePersonDialog.vue:65 \u00B7 resources/js/v8/components/forms/album/AlbumCreatePersonDialog.vue:63 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumCreatePersonDialog.vue"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"00c0d93c92d6a9b2200366f699899ab574cf610fa865ac74d6e933348020097e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2 locations): resources/js/v7/components/forms/album/AlbumCreateTagDialog.vue:65 \u00B7 resources/js/v8/components/forms/album/AlbumCreateTagDialog.vue:63 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumCreateTagDialog.vue"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"33ccb8d116ebe9c4c4f330fff1903d8009b247e7972362a201e41dd436d3ee90"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2 locations): resources/js/v7/components/forms/basic/InputCurrency.vue:18 \u00B7 resources/js/v8/components/forms/basic/InputCurrency.vue:15 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/InputCurrency.vue"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d70280b7604bcafe545cbe8f2cd741be91cedfa4503f499f646dad2fb629418"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 3 locations): resources/js/v7/components/forms/webhooks/WebhookFormDialog.vue:187 \u00B7 resources/js/v8/components/forms/landing/LandingLinkFormDialog.vue:128 \u00B7 resources/js/v8/components/forms/webhooks/WebhookFormDialog.vue:190 \u2014 the 3 copies are spread across 3 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 3 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/webhooks/WebhookFormDialog.vue"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd8528c6dfe033b1431cd0b0c366435ae684c45d78bf1bc6418447dfb1291ff9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2 locations): resources/js/v7/views/admin/NsfwConfig.vue:315 \u00B7 resources/js/v8/views/admin/NsfwConfig.vue:272 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"80092759817924b1f918799c7fdc08a23472a1a4ea9c52369c6da6863e2d9829"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2 locations): resources/js/v7/views/admin/Webhooks.vue:111 \u00B7 resources/js/v8/views/admin/Webhooks.vue:94 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Webhooks.vue"},"region":{"startLine":111}}}],"partialFingerprints":{"codehealthFindingId/v1":"12918c5d08273b92dbc563c09ae1a3446a9d2697e7fb115b309eb96110f61ad1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2 locations): resources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbVirtual.vue:128 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/AlbumThumb.vue:133 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbVirtual.vue"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9a1130d9d02220848c9d92896a78432fc2308310f30295825878befa18886a2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (19 matched lines \u00D7 2 locations): resources/js/v8/components/gallery/albumModule/Virtualized/PhotoGridVirtual.vue:583 \u00B7 resources/js/v8/composables/album/albumDateScrubber.ts:55 \u2014 the two spans are one implementation copied and then locally edited \u2014 79 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/PhotoGridVirtual.vue"},"region":{"startLine":583}}}],"partialFingerprints":{"codehealthFindingId/v1":"0174b2618cc847fa3a27d948930724293430b1d18a6dda22c4f5edb77218d1de"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 3 locations): resources/js/services/oauth-service.ts:13 \u00B7 resources/js/v7/components/maintenance/MaintenanceGenSizevariants.vue:53 \u00B7 resources/js/v8/components/maintenance/MaintenanceGenSizevariants.vue:38 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/oauth-service.ts"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"79ce956014ae9efdee71662bf5e68a47503d30a4bf4d4610e623940d390d42c7"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2 locations): resources/js/v7/components/forms/gallery-dialogs/BuyMeDialog.vue:143 \u00B7 resources/js/v8/components/forms/gallery-dialogs/BuyMeDialog.vue:128 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/gallery-dialogs/BuyMeDialog.vue"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"3142515dd055381bbdf41a944c9ed2afb3d92998be8ac21bff35d78c93be8ce4"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2 locations): resources/js/v7/components/forms/tags/TagDeleteDialog.vue:44 \u00B7 resources/js/v8/components/forms/tags/TagDeleteDialog.vue:58 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/tags/TagDeleteDialog.vue"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"0252bd5bd6c17b1bdab204d70c5083115ed1804d921c7d064cb17931f90aacad"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/thumbs/PhotoThumb.vue:136 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/PhotoThumb.vue:157 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/PhotoThumb.vue"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"e288704a4ac91043b3120a291f8e8db76cc8c457e91c7a30c48eb14eb07788dc"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2 locations): resources/js/v7/components/gallery/photoModule/PhotoRatingWidget.vue:74 \u00B7 resources/js/v8/components/gallery/photoModule/PhotoRatingWidget.vue:74 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoRatingWidget.vue"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc220032ac27a5281ec9e565ca60198f747c6bbe6208780b6c5d6fa85c24514b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 3 locations): resources/js/v8/components/headers/AlbumHeader.vue:152 \u00B7 resources/js/v8/components/headers/AlbumsHeader.vue:180 \u00B7 resources/js/v8/components/headers/TimelineHeader.vue:137 \u2014 the 3 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it. There is one copy in each of 3 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/AlbumHeader.vue"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"e26762fcc8d7a70aa17414d0c1b5f5001777942b33f44b5b2888d0442495f5e6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2 locations): resources/js/v8/utils/panZoom.ts:236 \u00B7 resources/js/v8/utils/sphere.ts:183 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/panZoom.ts"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"8afedbc4e157babd9e84a4fafc545bd4af33bc89bbba5228f11a5117cab21ba3"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 3 locations): resources/js/composables/album/photoActions.ts:70 \u00B7 resources/js/v7/components/gallery/albumModule/AlbumPanel.vue:365 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumPanel.vue:467 \u2014 the 3 copies are spread across 3 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 3 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/photoActions.ts"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"18b5411ea30b822c2a46a359a2f71a6158fdf067ed464a51ac96849c2f383895"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (17 matched lines \u00D7 2 locations): resources/js/v7/components/forms/album/SelectDrag.vue:10 \u00B7 resources/js/v8/components/forms/album/SelectDrag.vue:10 \u2014 the two spans are one implementation copied and then locally edited \u2014 140 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/SelectDrag.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"10422cf47eecb04b0540d67f811567db9ca2129d0587c0e754d4f670d1c5b9f1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 7 locations): resources/js/v7/components/forms/settings/SelectField.vue:35 \u00B7 resources/js/v7/components/forms/settings/SliderField.vue:39 \u00B7 resources/js/v7/components/forms/settings/StringField.vue:48 \u00B7 resources/js/v7/components/forms/settings/ZipSliderField.vue:30 \u00B7 \u002B3 more site(s) not listed \u2014 the 7 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 7 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SelectField.vue"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"9aabc50695a6dd8b56e8fc56d020629509c230480f65606a99cf7d4887fc2b10"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 3 locations): resources/js/v7/components/gallery/albumModule/AlbumListItem.vue:107 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumListItem.vue:142 \u00B7 resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListItemVirtual.vue:131 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumListItem.vue"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"d24b590208928dac46a15ec38bccf3188b2ab9e5d39b43fd372da701ab0ec414"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): resources/js/v7/components/gallery/photoModule/PhotoBox.vue:226 \u00B7 resources/js/v8/components/gallery/photoModule/PhotoBox.vue:561 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoBox.vue"},"region":{"startLine":226}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbba919e0866392ffbda3b220746b95308e638339b9bbac3db678828ebaffb9c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): resources/js/v7/components/modals/ImportFromLink.vue:51 \u00B7 resources/js/v8/components/modals/ImportFromLink.vue:43 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/ImportFromLink.vue"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"754b250fc2e8bc75d4d468388f8e5dc99e21a8ff2cc818c59f40e0088293c1a8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): resources/js/v7/components/modals/InviteUser.vue:34 \u00B7 resources/js/v8/components/modals/InviteUser.vue:34 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/InviteUser.vue"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"b64ded8a1f52ab612ba39948d2d6c79a34c15cf5d07f74341e6937f484994f1a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): resources/js/v7/components/pagination/Pagination.vue:39 \u00B7 resources/js/v8/components/pagination/Pagination.vue:31 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/pagination/Pagination.vue"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"b15fbe59fe1255d7142b674cd7e7cea5fff2db9741a63ac9c3ee94964c148ff3"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): resources/js/v7/components/settings/ConfigGroup.vue:217 \u00B7 resources/js/v8/components/settings/ConfigGroup.vue:241 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/ConfigGroup.vue"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"f957ab70fa13c052f0c77427927055f820bde2258d6ae6d5037bd8582bbd97af"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): resources/js/v7/router/routes.ts:97 \u00B7 resources/js/v8/router/routes.ts:115 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/router/routes.ts"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"88cb7558596d565c602ba08093dd9fb6ef2657b013a4b6f9afe6a8b3d21b6c7e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): resources/js/v7/views/FixTree.vue:131 \u00B7 resources/js/v8/views/FixTree.vue:229 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/FixTree.vue"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"5761c0edb6b6fffbe790d008cd5e964079d606a9e7da745cea253731ea57f1c1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Map.vue:97 \u00B7 resources/js/v8/views/gallery-panels/Map.vue:149 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Map.vue"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"374fecf990d71dcc322f7b9cc30aa46c4173695da2f651d9074ea37c5ce5bdb6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): resources/js/v8/components/gallery/albumModule/PhotoListItem.vue:114 \u00B7 resources/js/v8/components/gallery/albumModule/Virtualized/PhotoListItemVirtual.vue:123 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/PhotoListItem.vue"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"72cf87d750e03a7d3e851e1abd39c61d03f69c888c32030ebe521a8ac298ae88"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): resources/js/v8/components/modals/SpotlightSearch.vue:180 \u00B7 resources/js/v8/components/modals/SpotlightSearch.vue:197 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/SpotlightSearch.vue"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"2deb776e19081a95e14514c266a71410f24a7eb1bc05d023fdd7916dc6d949e5"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): resources/js/v8/views/LoginPage.vue:78 \u00B7 resources/js/v8/views/RegisterPage.vue:165 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/LoginPage.vue"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"ccbf9b277b698411e7751b85e8481e854671ca059e66ecb6e5771285dd07ec18"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): resources/js/v8/views/gallery-panels/Flow.vue:345 \u00B7 resources/js/v8/views/gallery-panels/Flow.vue:363 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Flow.vue"},"region":{"startLine":345}}}],"partialFingerprints":{"codehealthFindingId/v1":"71c8cfc824a50a85c55678d7ea677c3070bc76ff83db7e9288b07dcd2297f2e4"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (16 matched lines \u00D7 2 locations): resources/js/stores/AlbumListState.ts:67 \u00B7 resources/js/stores/GlobalRightsState.ts:18 \u2014 the two spans are one implementation copied and then locally edited \u2014 84 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumListState.ts"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"8097c2973b25a692c8c9981c3e3c500e48117548391db198c8734a77ac6cf081"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 3 locations): resources/js/v7/components/forms/photo/PhotoLicenseDialog.vue:42 \u00B7 resources/js/v7/components/forms/photo/PhotoTagDialog.vue:58 \u00B7 resources/js/v8/components/forms/photo/PhotoTagDialog.vue:46 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/photo/PhotoLicenseDialog.vue"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"92b1db0ead0a9a788a67c47b9ba4c17ad1ab58388f418efc5965672467053ea4"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): resources/js/v7/components/gallery/photoModule/FaceOverlay.vue:128 \u00B7 resources/js/v8/components/gallery/photoModule/FaceOverlay.vue:116 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/FaceOverlay.vue"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdcf0dde691640174bbda28432903be85d26a9c3dcb652126028136e3f43d4f6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): resources/js/v7/components/gallery/photoModule/MapInclude.vue:8 \u00B7 resources/js/v8/components/gallery/photoModule/MapInclude.vue:8 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/MapInclude.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc9ac8f132ff1fbfd5d846003619f46b2747e133ffcf04b2a2e5c88facca00c1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): resources/js/v7/components/gallery/searchModule/ResultPanel.vue:64 \u00B7 resources/js/v8/components/gallery/searchModule/ResultPanel.vue:84 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/searchModule/ResultPanel.vue"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"da90df7de9ccf46fbcf7a7880cc6cfdc664e597746345550c2020efa8b23d702"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): resources/js/v7/components/maintenance/MaintenanceBulkScanNsfw.vue:41 \u00B7 resources/js/v8/components/maintenance/MaintenanceBulkScanNsfw.vue:25 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceBulkScanNsfw.vue"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"cedac609a55c6a69769361560da78d5925451d8b145c4f3cc1cd3fc3861437f2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): resources/js/v7/components/modals/AboutLychee.vue:69 \u00B7 resources/js/v8/components/modals/AboutLychee.vue:62 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/AboutLychee.vue"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc354779b218304a656cab70ce391e44b2d4dee3569dbe229a8d02ee1c5e73ac"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): resources/js/v7/views/LoginPage.vue:56 \u00B7 resources/js/v8/views/LoginPage.vue:61 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/LoginPage.vue"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6a33e6fce3029c5bc975603e2558e8e14bd8fd8dd6d3eb200083c01ef8764ae"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Search.vue:560 \u00B7 resources/js/v7/views/gallery-panels/Timeline.vue:493 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Search.vue"},"region":{"startLine":560}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2e6cd16594ae4a21eb5e4e21434070637813d444379669de56e8ef3c21bbbb0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 3 locations): resources/js/v8/components/gallery/albumModule/AlbumPanel.vue:388 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumPanel.vue:530 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumPanel.vue:606 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumPanel.vue"},"region":{"startLine":388}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dd12d5f351c0cf01d661f09235a88c67e31264e3d61c2308113e85df2525a04"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): resources/js/v8/components/gallery/albumModule/Virtualized/PhotoThumbVirtual.vue:224 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/PhotoThumb.vue:217 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/PhotoThumbVirtual.vue"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c531f92910776fc5f6a3e27807d4cffec91230ca4c16537e63863864164d056"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): resources/js/v8/components/headers/AlbumsHeader.vue:349 \u00B7 resources/js/v8/components/headers/TimelineHeader.vue:262 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/AlbumsHeader.vue"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"be3c6ec8ba6a4e9600f6e03c0a296a3fd8c2506233f20338257cfbef2571dd2d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): resources/js/v8/composables/photo/analyticPhotoLayout.ts:159 \u00B7 resources/js/v8/composables/photo/analyticPhotoLayout.ts:397 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/photo/analyticPhotoLayout.ts"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"8fa7c4589483f0cba2963e285b3fbbd55a7579dcc41ce6b2b29c06f6cd16f0e9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): resources/js/v8/views/admin/Purchasables.vue:53 \u00B7 resources/js/v8/views/webshop/PurchasablesList.vue:47 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/Purchasables.vue"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1e79acac030804d51b0b498284ef67473bc044de2e66f15c8ae33019835a325"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2 locations): resources/js/composables/checkout/useMollie.ts:18 \u00B7 resources/js/composables/checkout/usePaypal.ts:9 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/checkout/useMollie.ts"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bde08ac72a861ec5564db1e834b27e1d125122cf250056876694d6788423076"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2 locations): resources/js/stores/AlbumsState.ts:180 \u00B7 resources/js/stores/AlbumsState.ts:208 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumsState.ts"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fd002e1454cb02a305ad5ac56689f11ad067ead939efa438864b804387562ee"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (15 matched lines \u00D7 2 locations): resources/js/v7/components/forms/search/SearchInputBar.vue:44 \u00B7 resources/js/v8/components/forms/search/SearchInputBar.vue:63 \u2014 the two spans are one implementation copied and then locally edited \u2014 111 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/SearchInputBar.vue"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9b2ef972f46467b509a03e2bb9779d2c0bd165cd0e5cf2139d9daa8be0fbe9b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2 locations): resources/js/v7/components/gallery/flowModule/CarouselImages.vue:18 \u00B7 resources/js/v8/components/gallery/flowModule/CarouselImages.vue:19 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/CarouselImages.vue"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"31e55d5892f909a4c867425ac61623d6679aa77335815e7fcf3e2f045a70ecc1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2 locations): resources/js/v7/components/headers/AlbumHeader.vue:129 \u00B7 resources/js/v8/components/headers/AlbumHeader.vue:119 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/AlbumHeader.vue"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"82e1b51b8d9ddcd234d823122aeee6d52404c38c90d4aa966114b62fb1bff59b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2 locations): resources/js/v7/components/maintenance/MaintenanceRunClustering.vue:49 \u00B7 resources/js/v8/components/maintenance/MaintenanceRunClustering.vue:34 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceRunClustering.vue"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"7bd3c642b1e5ec18aaa8c642420da894ee49bbf179764df0979a9c8bd7161e38"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2 locations): resources/js/v7/views/admin/NsfwConfig.vue:498 \u00B7 resources/js/v8/views/admin/NsfwConfig.vue:468 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":498}}}],"partialFingerprints":{"codehealthFindingId/v1":"e37b77a56bd18e7fe7ed1928c4491f45f4f161c59fe23498fc23ac064903fd0e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 4 locations): resources/js/v8/components/maintenance/MaintenanceBulkScanFaces.vue:23 \u00B7 resources/js/v8/components/maintenance/MaintenanceDestroyDismissedFaces.vue:23 \u00B7 resources/js/v8/components/maintenance/MaintenanceResetFaceScanStatus.vue:23 \u00B7 resources/js/v8/components/maintenance/MaintenanceSyncFaceEmbeddings.vue:23 \u2014 the 4 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it. There is one copy in each of 4 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceBulkScanFaces.vue"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"46a8080eed97ff9d3d254527efbea3971a6b8a60db91d92405341d5fb8fe56e0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2 locations): resources/js/v8/components/modals/faceRecog/BatchFaceAssignmentModal.vue:58 \u00B7 resources/js/v8/components/modals/faceRecog/FaceAssignmentModal.vue:115 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/faceRecog/BatchFaceAssignmentModal.vue"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a16eef81b66ae3695b18c9afb91f35a7494429389452cc431f0c916018df12d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (15 matched lines \u00D7 2 locations): resources/js/v8/views/admin/Moderation.vue:157 \u00B7 resources/js/v8/views/admin/NsfwFindings.vue:162 \u2014 the two spans are one implementation copied and then locally edited \u2014 169 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/Moderation.vue"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1ef77ea93dd6d3faab630f1874c538a89098515f893033b386a3c6e69768534"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (14 matched lines \u00D7 2 locations): resources/js/app-v8.ts:18 \u00B7 resources/js/app.ts:23 \u2014 the two spans are one implementation copied and then locally edited \u2014 70 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/app-v8.ts"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"f62c9c54489012b06e692da441681c2d835911f7b187e593710924717dd7e358"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2 locations): resources/js/embed/api.ts:132 \u00B7 resources/js/embed/api.ts:184 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/api.ts"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa57cf78bd36179da6142b625e490fa635a7e43279f6bbaf40d8a128bfb60c7c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2 locations): resources/js/services/album-service.ts:330 \u00B7 resources/js/v8/services/track-service.ts:10 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/album-service.ts"},"region":{"startLine":330}}}],"partialFingerprints":{"codehealthFindingId/v1":"517ef2c58fbb5c310cc21920a30c3578b9c7f75f95a50ba0995d9961638c7ca8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2 locations): resources/js/v7/components/faceRecog/FaceRecognitionWarning.vue:50 \u00B7 resources/js/v8/components/faceRecog/FaceRecognitionWarning.vue:44 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/faceRecog/FaceRecognitionWarning.vue"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"579c4886ae1b82ad24d859d9cca3aae80a9e13a6b334b31ae12c474537d26481"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2 locations): resources/js/v7/components/forms/basic/TagsInput.vue:54 \u00B7 resources/js/v8/components/forms/basic/TagsInput.vue:75 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/TagsInput.vue"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bb25f53a182c0eb59f414908964ceb915f2274c6a3f040d972d0b06c9c8762e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/PhotoListItem.vue:112 \u00B7 resources/js/v8/components/gallery/albumModule/PhotoListItem.vue:113 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoListItem.vue"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7e02dc0ea95fe9a7d72941f2ef5e50811500620e88def0d192cac47d888b6fd"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2 locations): resources/js/v7/components/webshop/PaymentInProgress.vue:16 \u00B7 resources/js/v8/components/webshop/PaymentInProgress.vue:19 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/PaymentInProgress.vue"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"e55124b4245688897b48ffd6eed5b52d92f290be89912b5d977b01d412649a43"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2 locations): resources/js/v7/components/webshop/ThankYou.vue:47 \u00B7 resources/js/v8/components/webshop/ThankYou.vue:44 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/ThankYou.vue"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"c422491bdb3c2dc0cc8afcaaf25d3d57e28f1a9df8f037ea298812e8a65e19ad"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2 locations): resources/js/v7/views/Home.vue:7 \u00B7 resources/js/v8/views/Home.vue:7 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Home.vue"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"699ae9bd45d1dd4ae284b154117388cd45d8b32bb552816a1386e54d9e195a2f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 3 locations): resources/js/v8/layouts/useGrid.ts:9 \u00B7 resources/js/v8/layouts/useMasonry.ts:9 \u00B7 resources/js/v8/layouts/useSquare.ts:9 \u2014 the 3 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it. There is one copy in each of 3 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/layouts/useGrid.ts"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab88d9bc3c8f460ec1e977be54ff3b74e81e56f14716e01d745dc8148ef469cb"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2 locations): resources/js/v8/views/landing/LandingPortfolio.vue:145 \u00B7 resources/js/v8/views/landing/LandingStudio.vue:116 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/landing/LandingPortfolio.vue"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6483f1d7a60ee87d6fa87160d57a3668c849e7a23716d42db02165d2bd80ba5"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): resources/js/services/auth-service.ts:29 \u00B7 resources/js/services/init-service.ts:14 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/auth-service.ts"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"df24b8327e131deb91c2c955866ca259ab0ecfca10fc3cd9030cfc191e8ef514"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): resources/js/stores/PhotoState.ts:262 \u00B7 resources/js/stores/PhotoState.ts:276 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/PhotoState.ts"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a470c1ca2ad648aff8164a31a2f4647e6651bd8fd18e0d5679b9db48373b2ed"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (13 matched lines \u00D7 2 locations): resources/js/v7/components/forms/basic/InputPassword.vue:22 \u00B7 resources/js/v7/components/forms/basic/InputText.vue:25 \u2014 the two spans are one implementation copied and then locally edited \u2014 91 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/InputPassword.vue"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"6eaad894469f2070b2a2cec6b57dbe1c25da62976c8d7e326ac9e6e6013c1e4c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): resources/js/v7/components/gallery/photoModule/PhotoBox.vue:258 \u00B7 resources/js/v8/components/gallery/photoModule/PhotoBox.vue:599 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoBox.vue"},"region":{"startLine":258}}}],"partialFingerprints":{"codehealthFindingId/v1":"df7f9b04ea3fb9718506199b2fd8d9e073d5e31371e3d171dbeb87643f117056"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): resources/js/v7/views/admin/Webhooks.vue:136 \u00B7 resources/js/v8/views/admin/Webhooks.vue:129 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Webhooks.vue"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"943d0ad6552207ce26fe10598d28059d837510ae330292cac1ec81a107db4853"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Map.vue:74 \u00B7 resources/js/v8/views/gallery-panels/Map.vue:85 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Map.vue"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"8518a4b717397d0cc42418f005ff29a3a65a26b0e141bbfd21789eac578fc65e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): resources/js/v8/components/forms/auth/LoginForm.vue:129 \u00B7 resources/js/v8/components/modals/WebauthnModal.vue:72 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/auth/LoginForm.vue"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b9a1bc7cb023547562c9980531e9c4aaff8724bce73708c287219b534f6f9f1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): resources/js/v8/composables/landing/useLandingCtaPosition.ts:34 \u00B7 resources/js/v8/views/admin/WatermarkPreview.vue:397 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/landing/useLandingCtaPosition.ts"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb0db81e9dd7d7f5d97c67930838178b3229b6cef634df5feda8fe8b330ef32e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): resources/js/v8/composables/usePanZoom.ts:236 \u00B7 resources/js/v8/composables/useSphereViewer.ts:397 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/usePanZoom.ts"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"699fe73104c7aeb91061cc7e48b01bb4a53f67ee19302f6aa4bd131d54f775aa"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): resources/js/v8/views/admin/ContactMessages.vue:211 \u00B7 resources/js/v8/views/admin/Webhooks.vue:156 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/ContactMessages.vue"},"region":{"startLine":211}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb04a8a8518290058ca762ff50ff8d1a167f7d2cbd7a169779677ca5b0887a75"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2 locations): resources/js/stores/AlbumState.ts:564 \u00B7 resources/js/stores/AlbumState.ts:585 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumState.ts"},"region":{"startLine":564}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7b830ab63e72d4038f0a4037513fe7513b85a28ea83c2b7836728aa7c0a1345"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2 locations): resources/js/v7/components/forms/album/AlbumTransfer.vue:43 \u00B7 resources/js/v8/components/forms/album/AlbumTransfer.vue:36 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumTransfer.vue"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"e35489b148cf14af1fe129bdf8bc642fd4d4e5a75b20cbf5f266265d65b96051"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/AlbumListView.vue:22 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumListView.vue:22 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumListView.vue"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8b1117d89795185c5efca9d743ac9b587fc14f287fdf4c4842044db6c1b58e0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/AlbumThumbPanelList.vue:20 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumThumbPanelList.vue:20 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumThumbPanelList.vue"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"f635ba4ea04bfb193b462da367504adc31b8cfad963cbe522552d441563871dc"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2 locations): resources/js/v7/components/maintenance/MaintenanceFixTree.vue:50 \u00B7 resources/js/v8/components/maintenance/MaintenanceFixTree.vue:40 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFixTree.vue"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"45fb24bd0a427256eca30b17d5dcf4580191e69c537a52b3e141e86f1eb15891"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2 locations): resources/js/v7/components/maintenance/MaintenanceFlushCache.vue:35 \u00B7 resources/js/v8/components/maintenance/MaintenanceFlushCache.vue:25 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFlushCache.vue"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"be7e515047ac65a1ba78744dca57d1418db64e7a3e488a78c0d2bd894860b85a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2 locations): resources/js/v7/components/modals/KeybindingsHelp.vue:146 \u00B7 resources/js/v8/components/modals/KeybindingsHelp.vue:149 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of DECLARATIONS inside a construct \u2014 the members of a type, or the entries of an object or array literal \u2014 with no statement anywhere in it. Do not read this as an extract-a-helper row: nothing here executes, so there is no call site, and a call expression cannot stand where a member declaration or a literal\u0027s entry was. What repeats is a SHAPE, and which shape decides the move. Where the copies declare the same members, the repetition is a missing common ancestor: give it a base type, an interface both extend, a generic instantiated twice, or \u2014 where the copies are a literal\u0027s entries rather than a type\u0027s members \u2014 one shared constant each site spreads or refers to, so the set is written once. Where they declare DIFFERENT members and only the form is shared \u2014 a decorator and its options, an annotation, a registration table\u0027s keys \u2014 the form is prescribed by a framework or a schema rather than copied, and the only collapse available is to generate the declarations from that schema; where you do not own the generator, this is the cost of the framework and there is nothing to extract. Check which of the two it is before acting: these copies still drift apart the first time only one of them is edited, which is why the repetition is reported, but the sentence to act on is not the same in both cases."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/KeybindingsHelp.vue"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"26867b2c4bbe000e3ce12b80117a327a5c78fa577c8a325b9504da17e134ba15"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2 locations): resources/js/v7/components/renamer/RenamerRuleLine.vue:53 \u00B7 resources/js/v8/components/renamer/RenamerRuleLine.vue:45 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/renamer/RenamerRuleLine.vue"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"88995178abdfc260a32f0f1739dbdc7dcfaabba11340995f64e3782f8b146996"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2 locations): resources/js/v7/views/admin/NsfwConfig.vue:394 \u00B7 resources/js/v8/views/admin/NsfwConfig.vue:357 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"19dbed56502c14ccc01268a5580f8153a55bc418cb984196c8bc0113a98df460"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3 locations): resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListViewVirtual.vue:72 \u00B7 resources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbGridVirtual.vue:100 \u00B7 resources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbPanelVirtual.vue:58 \u2014 the 3 copies are spread across 3 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListViewVirtual.vue"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2ed5a7c6bd531f0e13e25586c1c3a5870c30503ddbf90af580637c55d381819"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2 locations): resources/js/v8/composables/album/treeOperations.ts:96 \u00B7 resources/js/v8/composables/album/treeOperations.ts:110 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/treeOperations.ts"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"29eb126130047f47dda04725ac1710bc4ce7087fed715cc1d5b708532fa0f49a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 5 locations): resources/js/composables/album/photoActions.ts:102 \u00B7 resources/js/v7/views/face-recog/PersonDetail.vue:520 \u00B7 resources/js/v7/views/gallery-panels/Flow.vue:148 \u00B7 resources/js/v8/views/face-recog/PersonDetail.vue:532 \u00B7 \u002B1 more site(s) not listed \u2014 the 5 copies are spread across 5 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/photoActions.ts"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fbd84d498cf62923746660a7f4a39129fa24a15cb529224f6e6bac8c8e5b618"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): resources/js/stores/AlbumState.ts:351 \u00B7 resources/js/stores/AlbumState.ts:609 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumState.ts"},"region":{"startLine":351}}}],"partialFingerprints":{"codehealthFindingId/v1":"36e1366c74cf33084514e55c9922b2ebb5e9b3d0d66929c5224153340fe113d1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 4 locations): resources/js/v7/components/diagnostics/ConfigurationsDiagnostics.vue:12 \u00B7 resources/js/v7/components/diagnostics/InfoDiagnostics.vue:12 \u00B7 resources/js/v8/components/diagnostics/ConfigurationsDiagnostics.vue:14 \u00B7 resources/js/v8/components/diagnostics/InfoDiagnostics.vue:14 \u2014 the 4 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 4 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/diagnostics/ConfigurationsDiagnostics.vue"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"21ea42c2065886f2e877690930e0707350b06e8894c9447a18183258219b743b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): resources/js/v7/components/forms/people/PersonDeleteDialog.vue:41 \u00B7 resources/js/v8/components/forms/people/PersonDeleteDialog.vue:48 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/people/PersonDeleteDialog.vue"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"6273fef99cea2203bc9f3496158c50eee0f1c5eb8784667fb51557c02b83ca80"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 6 locations): resources/js/v7/components/forms/profile/SetSharedAlbumsVisibility.vue:114 \u00B7 resources/js/v8/components/forms/profile/SetSharedAlbumsVisibility.vue:103 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumPanel.vue:395 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumPanel.vue:537 \u00B7 \u002B2 more site(s) not listed \u2014 the 6 copies are spread across 4 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetSharedAlbumsVisibility.vue"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9423003edeb8898ae5b3041b66b115b0996d5bbcb37ea5b56ff21557fa5c6b1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/AlbumPeopleFilter.vue:44 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumPeopleFilter.vue:43 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumPeopleFilter.vue"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf258a583e148e40253e42759f50c24f2ba40c1f958e9f15cf5e8760fdcf4226"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/thumbs/ThumbRatingOverlay.vue:18 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/ThumbRatingOverlay.vue:18 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ThumbRatingOverlay.vue"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"1862bed5ff981881613b50c0514acb2853e00dbf81199855d4dc54565f0bcb3b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): resources/js/v7/components/gallery/flowModule/TopImages.vue:34 \u00B7 resources/js/v8/components/gallery/flowModule/TopImages.vue:35 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/TopImages.vue"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"76bdfde76c71b56e7b4165a03f38e082dc233437b5acba55f0eb52c332f96cff"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): resources/js/v7/components/maintenance/MaintenanceOptimize.vue:42 \u00B7 resources/js/v8/components/maintenance/MaintenanceOptimize.vue:28 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceOptimize.vue"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"11b891a12a52160bd32c3e7a55c522dfe0c41f85063336cfcceffbc4b38d0c63"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (11 matched lines \u00D7 2 locations): resources/js/v7/menus/LeftMenu.vue:155 \u00B7 resources/js/v8/composables/useLogout.ts:32 \u2014 the two spans are one implementation copied and then locally edited \u2014 71 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/menus/LeftMenu.vue"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"7cbf1c8327452407bfbb3b91b02999b3a13c31d53840bf9293c3057c4e896205"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3 locations): resources/js/v7/views/face-recog/FaceClusters.vue:355 \u00B7 resources/js/v7/views/face-recog/People.vue:214 \u00B7 resources/js/v8/views/face-recog/People.vue:255 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":355}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a15ec2fe742d5c188ab5087ecaf73a7d62c52c654e1949760e2f06fe6a08ef0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3 locations): resources/js/v7/views/face-recog/FaceClusters.vue:472 \u00B7 resources/js/v7/views/face-recog/FaceClusters.vue:490 \u00B7 resources/js/v8/views/face-recog/FaceClusters.vue:731 \u2014 the 3 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":472}}}],"partialFingerprints":{"codehealthFindingId/v1":"230dc82a6929bc5c708e218c3eb8b00b359c61c6b2c118a0f14c71155281967b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Album.vue:407 \u00B7 resources/js/v7/views/gallery-panels/Search.vue:513 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Album.vue"},"region":{"startLine":407}}}],"partialFingerprints":{"codehealthFindingId/v1":"978769837910fbbb72d5eeb5e3d536a9ca5fe009c9f9da9be2ee72ae0c48a7a5"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): resources/js/v8/components/forms/album/AlbumProperties.vue:545 \u00B7 resources/js/v8/components/forms/album/AlbumProperties.vue:573 \u2014 all 2 copies are in the same file, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumProperties.vue"},"region":{"startLine":545}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f14c18f3a06c7025c2983b2852f8dd633d559d1a94e3207a59ff16e865cb08d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): resources/js/v8/views/gallery-panels/Album.vue:391 \u00B7 resources/js/v8/views/gallery-panels/Tag.vue:195 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Album.vue"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f5586b22f04c6261b8c8b0edc5d9bcf53dc5ec58aa52308141d8a11efa8c867"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): resources/js/v8/views/gallery-panels/Map.vue:471 \u00B7 resources/js/v8/views/gallery-panels/Map.vue:687 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Map.vue"},"region":{"startLine":471}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dac5476f94ccd85e312154a7153d979091b8c55654ad528111739644c62355c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2 locations): resources/js/composables/photo/getNextPreviousPhoto.ts:8 \u00B7 resources/js/composables/photo/getNextPreviousPhoto.ts:23 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/photo/getNextPreviousPhoto.ts"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"38ea472854b18e6f7826cbdc5148e73863094e7745fc7b9bdc608681c0ea551b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (10 matched lines \u00D7 2 locations): resources/js/composables/photo/slideshow.ts:47 \u00B7 resources/js/v8/composables/frame/frameSlideshow.ts:16 \u2014 the two spans are one implementation copied and then locally edited \u2014 54 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/photo/slideshow.ts"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"d18a0146852df758e93e645e42f2c07ab7310eedd8d3f6b4dc8d819185fb78a2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2 locations): resources/js/layouts/useJustify.ts:8 \u00B7 resources/js/v8/layouts/useJustify.ts:10 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/useJustify.ts"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"38cb16916a1651d322a4c522fe305bf45bbbaf6b8d404c9cd7140b4355c671ee"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 5 locations): resources/js/services/maintenance-service.ts:41 \u00B7 resources/js/services/maintenance-service.ts:94 \u00B7 resources/js/services/maintenance-service.ts:108 \u00B7 resources/js/services/maintenance-service.ts:120 \u00B7 \u002B1 more site(s) not listed \u2014 all 5 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/maintenance-service.ts"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"db675e4acc23083d9e69f3ae10395f88f17b836d012a8a1a966a14536d5c4263"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (10 matched lines \u00D7 2 locations): resources/js/stores/TimelineState.ts:356 \u00B7 resources/js/v8/components/gallery/albumModule/Virtualized/PhotoGridVirtual.vue:714 \u2014 the two spans are one implementation copied and then locally edited \u2014 53 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/TimelineState.ts"},"region":{"startLine":356}}}],"partialFingerprints":{"codehealthFindingId/v1":"26b1f71a25f1d02542083deab2d5a679b3bec87aa4c2e92c411eedc2b8dec756"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2 locations): resources/js/v7/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue:189 \u00B7 resources/js/v8/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue:192 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of DECLARATIONS inside a construct \u2014 the members of a type, or the entries of an object or array literal \u2014 with no statement anywhere in it. Do not read this as an extract-a-helper row: nothing here executes, so there is no call site, and a call expression cannot stand where a member declaration or a literal\u0027s entry was. What repeats is a SHAPE, and which shape decides the move. Where the copies declare the same members, the repetition is a missing common ancestor: give it a base type, an interface both extend, a generic instantiated twice, or \u2014 where the copies are a literal\u0027s entries rather than a type\u0027s members \u2014 one shared constant each site spreads or refers to, so the set is written once. Where they declare DIFFERENT members and only the form is shared \u2014 a decorator and its options, an annotation, a registration table\u0027s keys \u2014 the form is prescribed by a framework or a schema rather than copied, and the only collapse available is to generate the declarations from that schema; where you do not own the generator, this is the cost of the framework and there is nothing to extract. Check which of the two it is before acting: these copies still drift apart the first time only one of them is edited, which is why the repetition is reported, but the sentence to act on is not the same in both cases."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"77e947b4c44760f1e303884e3c064dc4631f229eb74833e0569b7c1b8e5722c6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3 locations): resources/js/v7/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue:299 \u00B7 resources/js/v8/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue:372 \u00B7 resources/js/v8/components/forms/bulk-album-edit/BulkSetOwnerDialog.vue:82 \u2014 the 3 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 3 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue"},"region":{"startLine":299}}}],"partialFingerprints":{"codehealthFindingId/v1":"8278799157e834adecf049b82dc1b8e8c9063d1f89fd5d051a3d564e4fcc4d49"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (10 matched lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/thumbs/ThumbBadge.vue:10 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/ThumbBadge.vue:16 \u2014 the two spans are one implementation copied and then locally edited \u2014 87 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ThumbBadge.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"178b36c452006eea043444050858c29b4cc7c44e7731ab23b62ee53f2ec681b3"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2 locations): resources/js/v7/components/gallery/photoModule/NextPrevious.vue:30 \u00B7 resources/js/v8/components/gallery/photoModule/NextPrevious.vue:39 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/NextPrevious.vue"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"f15f27cdf6829efd04b05d0cca657492d6c4b8aafc67ac5e42812725e82f54d1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (10 matched lines \u00D7 2 locations): resources/js/v7/components/gallery/searchModule/SearchPanel.vue:10 \u00B7 resources/js/v8/components/gallery/searchModule/SearchPanel.vue:12 \u2014 the two spans are one implementation copied and then locally edited \u2014 54 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/searchModule/SearchPanel.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"dce0cf749ddcb7a6a98f61383a72e153bbfbabd8f97407425f4bcc7f45f09a8d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2 locations): resources/js/v7/components/settings/ConfirmSave.vue:81 \u00B7 resources/js/v8/components/settings/ConfirmSave.vue:86 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/ConfirmSave.vue"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"c904a64359f701371d474e63efa652d3c7d5d7fe86f09fb069cbed7db6ace01a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2 locations): resources/js/v7/views/BulkAlbumEdit.vue:333 \u00B7 resources/js/v8/views/BulkAlbumEdit.vue:302 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":333}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ef2c439b86a713289bcf29bb902ea2c5337eef3901dff0a413a9667cef5282f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2 locations): resources/js/v7/views/face-recog/FaceClusters.vue:420 \u00B7 resources/js/v7/views/face-recog/FaceClusters.vue:574 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":420}}}],"partialFingerprints":{"codehealthFindingId/v1":"09edbdeb3aae278eab95eabd2a62fd11da0d61ca821668a135bc8bd0ef04105e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2 locations): resources/js/v8/components/gallery/albumModule/AlbumPanel.vue:539 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumPanel.vue:615 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumPanel.vue"},"region":{"startLine":539}}}],"partialFingerprints":{"codehealthFindingId/v1":"1132e7bdd172b9709bb87c21b5e726de781b6748e1e9d2e5cca7a292604d048c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2 locations): resources/js/v8/views/admin/LandingConfig.vue:895 \u00B7 resources/js/v8/views/admin/WatermarkPreview.vue:344 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/LandingConfig.vue"},"region":{"startLine":895}}}],"partialFingerprints":{"codehealthFindingId/v1":"04fb5cd099c5b49c69012ee27fa35805c8da70d7511033fbbd69d538f4286f73"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2 locations): resources/js/composables/tags/tagsActions.ts:11 \u00B7 resources/js/v8/composables/tags/tagsActions.ts:6 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/tags/tagsActions.ts"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fef69a7a777ec4e0ce2fa7ac7b6a6049b39df02f1424f843991614a9b4e04ce"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2 locations): resources/js/services/album-service.ts:229 \u00B7 resources/js/services/album-service.ts:245 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/album-service.ts"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"523ec2dfa92e9ac9e531479d24634ff5c37bc778a680e35cb873d395651ec661"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2 locations): resources/js/services/contact-service.ts:9 \u00B7 resources/js/services/webshop-service.ts:65 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/contact-service.ts"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"f77f89a417cbff9490144d0f5d38299ebf9d02e5b474f77d93522f3a31403c66"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2 locations): resources/js/services/diagnostics-service.ts:4 \u00B7 resources/js/services/profile-service.ts:4 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/diagnostics-service.ts"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"31e61879b969f98d000d50304de511cbd75d509373c91cec12a41b3b13f83250"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2 locations): resources/js/services/map-v3-service.ts:33 \u00B7 resources/js/services/map-v3-service.ts:43 \u2014 all 2 copies are in the same file, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/map-v3-service.ts"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"e70d7f2b89cc34cd4c834d8ff26b91b960263205f1bf5a22e1287706b676346f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3 locations): resources/js/v7/components/forms/album/AlbumShare.vue:102 \u00B7 resources/js/v7/views/Sharing.vue:61 \u00B7 resources/js/v8/components/forms/album/AlbumShare.vue:117 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumShare.vue"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"495fc64a4e7d2861427b999109fe6ac60006154379c8263daac0917491accf70"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2 locations): resources/js/v7/components/forms/basic/PersonInput.vue:60 \u00B7 resources/js/v8/components/forms/basic/PersonInput.vue:64 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/PersonInput.vue"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1797c7904af74b675d24b4e14e1f00e9f8574c416593f3b8e34e5223f0c5cce"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2 locations): resources/js/v7/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue:172 \u00B7 resources/js/v8/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue:170 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"f193a3b918466269be7d7e870ddc960aed0ddf7192f580e88cd6cb565806f04a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3 locations): resources/js/v7/components/forms/tags/TagDeleteDialog.vue:32 \u00B7 resources/js/v7/components/forms/webhooks/WebhookDeleteDialog.vue:32 \u00B7 resources/js/v8/components/forms/webhooks/WebhookDeleteDialog.vue:39 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/tags/TagDeleteDialog.vue"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"d07c9c2b517d214360f1c264e482b60b793818ad1d58619305061e2fc4b4b722"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3 locations): resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumbDecorations.vue:17 \u00B7 resources/js/v7/components/webshop/OrderListAction.vue:44 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/AlbumThumbDecorations.vue:17 \u2014 the 3 copies are spread across 3 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumbDecorations.vue"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"299d4c2345669ad34892dbc3f8ddc493045e9b388e13ba3c5f822f45aa765556"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2 locations): resources/js/v7/views/admin/Purchasables.vue:77 \u00B7 resources/js/v7/views/webshop/PurchasablesList.vue:77 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Purchasables.vue"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"2490d9c1d11eb55de9779d74631072ce246b3cc26c472a57da239e416e894866"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Map.vue:139 \u00B7 resources/js/v8/views/gallery-panels/Map.vue:568 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Map.vue"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"04dbb8980168be95459fca5aacb5c96cfb0db84ad9ed3f29b4f9e5b2d7ca8a20"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (9 matched lines \u00D7 2 locations): resources/js/v8/components/forms/album/AlbumTracks.vue:101 \u00B7 resources/js/v8/components/forms/album/AlbumTracks.vue:153 \u2014 the two spans are one implementation copied and then locally edited \u2014 67 tokens are still identical, in the same order in both spans, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumTracks.vue"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad39c325711ef6cf54d8768e209b9929825801d06559f45ed29173f879b8307b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2 locations): resources/js/v8/components/forms/basic/InputPassword.vue:61 \u00B7 resources/js/v8/components/forms/basic/InputText.vue:24 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/InputPassword.vue"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0914b12ca2a6cd0efc6d98b6b0f91b8fc8a20b746926c78d1f175c676e0a46c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3 locations): resources/js/v8/views/RenamerRules.vue:206 \u00B7 resources/js/v8/views/admin/LandingConfig.vue:1014 \u00B7 resources/js/v8/views/admin/LandingConfig.vue:1147 \u2014 the 3 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/RenamerRules.vue"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba39e07cf0048dfe8082d594a5237393d0cb1eaf9c12eb7b3e11fb8e832def77"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/composables/album/folderDrop.ts:105 \u00B7 resources/js/composables/album/folderDrop.ts:151 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/folderDrop.ts"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"2779f85b86e6a57874fe74391a901be2ca47787abf9fc52e67e91ae868a34f51"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3 locations): resources/js/composables/album/photoActions.ts:90 \u00B7 resources/js/v7/views/gallery-panels/Search.vue:392 \u00B7 resources/js/v8/views/gallery-panels/Search.vue:452 \u2014 the 3 copies are spread across 3 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 3 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/photoActions.ts"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ab119b55c5e9e65df12f40f81e37154d561b59e8123d0fcae37bbf9b35d43ee"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/embed/config.ts:194 \u00B7 resources/js/embed/config.ts:204 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/config.ts"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"681a74e57aa240f078f20975eddde8cdf4cdb58298049763ff0d6852a7bf3230"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 5 locations): resources/js/services/album-category-v3-service.ts:55 \u00B7 resources/js/services/album-category-v3-service.ts:64 \u00B7 resources/js/services/album-category-v3-service.ts:73 \u00B7 resources/js/services/album-category-v3-service.ts:82 \u00B7 \u002B1 more site(s) not listed \u2014 all 5 copies are in the same file, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/album-category-v3-service.ts"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"55a5c296b4adc5fe7d8771ba2f4b7fa001b5c74029746853d9b48c03092bbeca"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/services/album-service.ts:121 \u00B7 resources/js/services/album-service.ts:148 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/album-service.ts"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab8d7ffca03e39a87d5c82c01b4196d06ef528e3c6985b3e21201e3b62da2e56"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/services/maintenance-service.ts:15 \u00B7 resources/js/services/maintenance-service.ts:36 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/maintenance-service.ts"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7e67c84b6ccda8dfaf3822e733928dcbd68c29c3c70f4e90f78c6acb95a74de"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3 locations): resources/js/services/search-v3-service.ts:71 \u00B7 resources/js/services/search-v3-service.ts:96 \u00B7 resources/js/services/search-v3-service.ts:105 \u2014 all 3 copies are in the same file, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/search-v3-service.ts"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"27877ad3e5729f5761af3940cc06bdc2e7ea7511b486d7b0341a73428a28cc56"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/stores/AlbumState.ts:1015 \u00B7 resources/js/stores/AlbumsState.ts:98 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumState.ts"},"region":{"startLine":1015}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa0964c9ba4632dca42af5301478d2630d5586895be969642ff56d83459dd1d1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/stores/AlbumsState.ts:295 \u00B7 resources/js/stores/AlbumsState.ts:303 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumsState.ts"},"region":{"startLine":295}}}],"partialFingerprints":{"codehealthFindingId/v1":"37a673368a8a830cd78a333ee4decb89514effa470f85141b0ea294244cd8d6f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/utils/StatsSizeVariantToColours.ts:38 \u00B7 resources/js/v8/composables/useSizeVariantStats.ts:44 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/utils/StatsSizeVariantToColours.ts"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"63577859f9b1faac2ea680be80724849d7c60c3c83a27a63906dc2874c88b686"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/v7/components/diagnostics/SpaceDiagnostics.vue:15 \u00B7 resources/js/v8/components/diagnostics/SpaceDiagnostics.vue:18 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/diagnostics/SpaceDiagnostics.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac1f9c0e877c0800388d74fd0f392f34cdfb9becad5ae66d01a02294062038a1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (8 matched lines \u00D7 2 locations): resources/js/v7/components/drawers/PhotoDetails.vue:442 \u00B7 resources/js/v7/components/modals/faceRecog/FaceAssignmentModal.vue:133 \u2014 the two spans are one implementation copied and then locally edited \u2014 83 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/PhotoDetails.vue"},"region":{"startLine":442}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d075c4cf2d05247851b51a33997ac677ce1cb9d54b4fe712b80bfaf8dfae266"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (8 matched lines \u00D7 2 locations): resources/js/v7/components/drawers/PhotoDetails.vue:442 \u00B7 resources/js/v8/components/modals/faceRecog/FaceAssignmentModal.vue:147 \u2014 the two spans are one implementation copied and then locally edited \u2014 83 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/PhotoDetails.vue"},"region":{"startLine":442}}}],"partialFingerprints":{"codehealthFindingId/v1":"1550968fc453020e7e0df3b23b931897af3cf0da6e6ea5f4650ee95e36359f8a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3 locations): resources/js/v7/components/forms/search/AdvancedSearchPanel.vue:215 \u00B7 resources/js/v7/components/statistics/Activity.vue:47 \u00B7 resources/js/v8/components/forms/search/AdvancedSearchPanel.vue:222 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c063938e4ffe6a0e3b367b8bf0497fa78d481d542131a30a3f9ceda7838e60d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/v7/components/forms/shop-management/PrintSizeFormDialog.vue:75 \u00B7 resources/js/v8/components/forms/shop-management/PrintSizeFormDialog.vue:58 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PrintSizeFormDialog.vue"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f5224834b3fc54c4bba0ed69fcc759ecba0650d36b235d28ef8d749d28fb461"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/AlbumHeaderImage.vue:16 \u00B7 resources/js/v8/components/gallery/albumModule/AlbumHeaderImage.vue:16 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumHeaderImage.vue"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"8cf54906bef9f75baf716c03672049e3702f1cdd108bba231c3114162a138045"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/SensitiveWarning.vue:29 \u00B7 resources/js/v8/components/gallery/albumModule/SensitiveWarning.vue:29 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"a20c0b41c2e85493a51c36a300c8d386366a865a832cea34fe4117af2f695e5c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (8 matched lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/thumbs/ListBadge.vue:10 \u00B7 resources/js/v7/components/gallery/albumModule/thumbs/ThumbBadge.vue:10 \u2014 the two spans are one implementation copied and then locally edited \u2014 78 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ListBadge.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5c71e23a7ef798b45aefd5584aeb51d2c8a861d2d1c62eeee9ba213c00cb8b4"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (8 matched lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/thumbs/ListBadge.vue:10 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/ThumbBadge.vue:16 \u2014 the two spans are one implementation copied and then locally edited \u2014 55 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ListBadge.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b82feb780e924a990055e522ddb14c58b0161304a85b4853d14557445de6496"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/v7/components/maintenance/MaintenanceDuplicateChecker.vue:49 \u00B7 resources/js/v8/components/maintenance/MaintenanceDuplicateChecker.vue:28 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceDuplicateChecker.vue"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"de56c359cb66982d4dff2317b755b404d8f8adef0f6f4b7bebdbf2c447ae7407"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/v7/components/modals/SessionExpiredReload.vue:37 \u00B7 resources/js/v8/components/modals/SessionExpiredReload.vue:25 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/SessionExpiredReload.vue"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"961dd513678750bf9667d902df3251988bc98a6b16ca5eb8b2af50e9dceaad2f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/v7/components/webshop/OrderDate.vue:19 \u00B7 resources/js/v8/components/webshop/OrderDate.vue:19 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderDate.vue"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fb9f7b55eec31a73e58e2d6472ad8abf5aa63ac518a3d862bb1c544a3a4a9c6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3 locations): resources/js/v7/components/webshop/OrderDate.vue:18 \u00B7 resources/js/v8/components/webshop/OrderDate.vue:18 \u00B7 resources/js/v8/components/webshop/OrderListAction.vue:48 \u2014 the 3 copies are spread across 3 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderDate.vue"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"98911b869c61bfc2311c99333f09d6b397df66147f824c790eb45c3b537a40e9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/v7/views/Landing.vue:115 \u00B7 resources/js/v8/views/Landing.vue:20 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Landing.vue"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"473446eb0a3724af530ec4efadd5dfab88b287e59e31a9508d6a284e6f7788e2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3 locations): resources/js/v8/components/forms/album/AlbumCreateShareDialog.vue:83 \u00B7 resources/js/v8/components/forms/sharing/BulkSharingModal.vue:107 \u00B7 resources/js/v8/components/forms/sharing/ShareLine.vue:42 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumCreateShareDialog.vue"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"9860611eddc3835677ac57a4971053764250fb0449c3609aab0fc42301c6f727"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/v8/components/gallery/timelineModule/TimelineDatesV3.vue:394 \u00B7 resources/js/v8/components/gallery/timelineModule/TimelineDatesV3.vue:415 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/timelineModule/TimelineDatesV3.vue"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"f03ff3d48c3d92a2abaeff0fc96e422ee012ea7162224e5e096a49aaad4fcb76"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/v8/views/gallery-panels/Frame.vue:94 \u00B7 resources/js/v8/views/gallery-panels/Search.vue:546 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Frame.vue"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c4c8dc67b34c3a39dccc97ac8c2ee35681eb56f785350359f31e5d0d46aab20"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/v8/views/gallery-panels/Map.vue:483 \u00B7 resources/js/v8/views/gallery-panels/Map.vue:708 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Map.vue"},"region":{"startLine":483}}}],"partialFingerprints":{"codehealthFindingId/v1":"16815890515b107fd7bb95ce0d5ac38877496d8ece3b80d2d4fb2fa89c53cda2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): resources/js/v8/views/landing/LandingClassic.vue:122 \u00B7 resources/js/v8/views/landing/LandingPortfolio.vue:110 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/landing/LandingClassic.vue"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"5308c2dcf7f0ab17ff613f337047c9813fa4ad66d3d2c9e2215137f7aec0468a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (8 matched lines \u00D7 2 locations): resources/js/v8/views/landing/LandingMeridian.vue:93 \u00B7 resources/js/v8/views/landing/LandingStudio.vue:89 \u2014 the two spans are one implementation copied and then locally edited \u2014 50 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/landing/LandingMeridian.vue"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"846af6fbd6a5b9ee798e4113e7b6a6666c2fce99fccbf866ca6b7fb6ee5fcc31"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2 locations): resources/js/composables/album/dragAndSelect.ts:520 \u00B7 resources/js/composables/album/dragAndSelect.ts:529 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/dragAndSelect.ts"},"region":{"startLine":520}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc429bd229187e9f3736b9a00eb9fc490f28c5d8a7707cb3173dc46bb1fbc5c3"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 4 locations): resources/js/services/album-category-v3-service.ts:23 \u00B7 resources/js/services/album-category-v3-service.ts:31 \u00B7 resources/js/services/album-category-v3-service.ts:39 \u00B7 resources/js/services/album-category-v3-service.ts:47 \u2014 all 4 copies are in the same file, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/album-category-v3-service.ts"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"5588bbbce57af52e5578b3b6ce746783f81184563bf27d1f5b63c8253571812d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3 locations): resources/js/services/album-children-v3-service.ts:13 \u00B7 resources/js/services/album-children-v3-service.ts:21 \u00B7 resources/js/services/album-children-v3-service.ts:29 \u2014 all 3 copies are in the same file, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/album-children-v3-service.ts"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa206179a85b33ca96a376a6e1ac9fa88816fb1b53d513b9d41aae1b6cf60e83"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3 locations): resources/js/services/album-list-v3-service.ts:11 \u00B7 resources/js/services/diagnostics-service.ts:26 \u00B7 resources/js/services/flow-service.ts:10 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/album-list-v3-service.ts"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"2bc2e156b16059bfa5c2dfd33ffe9ff2672c0ff5a244f619a601d1eb9640de15"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3 locations): resources/js/services/init-service.ts:41 \u00B7 resources/js/services/sharing-service.ts:52 \u00B7 resources/js/services/users-service.ts:13 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/init-service.ts"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"274a8cbc9590c014526e361f3a82d831979dad3fd82933e0a2cea3acf8f90159"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2 locations): resources/js/services/maintenance-service.ts:144 \u00B7 resources/js/services/maintenance-service.ts:156 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/maintenance-service.ts"},"region":{"startLine":144}}}],"partialFingerprints":{"codehealthFindingId/v1":"9dacc2d2bb5c1bcedaf40e6aa20c3c83a16b356a060d413f402186403086e689"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2 locations): resources/js/services/search-v3-service.ts:92 \u00B7 resources/js/services/search-v3-service.ts:101 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/search-v3-service.ts"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d95a0a3167315da0d2b657378cbb1f8bbef2c93b2be61fcb66d56150b009103"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3 locations): resources/js/services/settings-service.ts:5 \u00B7 resources/js/services/user-management-service.ts:17 \u00B7 resources/js/services/webauthn-service.ts:7 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/settings-service.ts"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"165ca2b106374f9de89febb487aa75c7b004a5b82483652f921af1ad1505fff3"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3 locations): resources/js/stores/AlbumState.ts:445 \u00B7 resources/js/stores/FlowState.ts:174 \u00B7 resources/js/stores/TimelineState.ts:395 \u2014 the 3 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it. There is one copy in each of 3 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumState.ts"},"region":{"startLine":445}}}],"partialFingerprints":{"codehealthFindingId/v1":"64de77c96156f73ff8bd9c3e64c2891d01ea6dcbae15289ed597a7d41fa616ae"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2 locations): resources/js/v7/components/drawers/AlbumEdit.vue:117 \u00B7 resources/js/v8/components/drawers/AlbumEdit.vue:139 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/AlbumEdit.vue"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"75f9a394d6533c961f1b7e05b9ee941823bebd4a96a472fa7098210bc31da251"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (7 matched lines \u00D7 2 locations): resources/js/v7/components/footers/GalleryFooter.vue:78 \u00B7 resources/js/v8/components/footers/GalleryFooter.vue:44 \u2014 the two spans are one implementation copied and then locally edited \u2014 63 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/GalleryFooter.vue"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"868e37356dfd30e8c74f397807c1a4d3c289813d7aaf3f07b0105b85ea78a7ab"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (7 matched lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/thumbs/ListBadge.vue:10 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/ListBadge.vue:10 \u2014 the two spans are one implementation copied and then locally edited \u2014 55 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ListBadge.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"221d6fe851bd9c1edd4a5f1a4931ad245105afb8de0ee968d7e99a6bffa26762"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (7 matched lines \u00D7 2 locations): resources/js/v7/components/gallery/albumModule/thumbs/ThumbBadge.vue:10 \u00B7 resources/js/v8/components/gallery/albumModule/thumbs/ListBadge.vue:10 \u2014 the two spans are one implementation copied and then locally edited \u2014 55 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ThumbBadge.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d83ebaf1936056574be443ff82aa54a8f9c88405dbb2703f29eaa36c02b4ec6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (7 matched lines \u00D7 2 locations): resources/js/v7/components/headers/LycheeBreadcrumb.vue:28 \u00B7 resources/js/v8/components/headers/LycheeBreadcrumb.vue:36 \u2014 the two spans are one implementation copied and then locally edited \u2014 59 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/LycheeBreadcrumb.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"7cd1f24923b042dee5ac389919a234b6455bf41e038205fbde8780c6e6380bc8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2 locations): resources/js/v7/components/modals/KeybindingsHelp.vue:133 \u00B7 resources/js/v8/components/modals/KeybindingsHelp.vue:134 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of DECLARATIONS inside a construct \u2014 the members of a type, or the entries of an object or array literal \u2014 with no statement anywhere in it. Do not read this as an extract-a-helper row: nothing here executes, so there is no call site, and a call expression cannot stand where a member declaration or a literal\u0027s entry was. What repeats is a SHAPE, and which shape decides the move. Where the copies declare the same members, the repetition is a missing common ancestor: give it a base type, an interface both extend, a generic instantiated twice, or \u2014 where the copies are a literal\u0027s entries rather than a type\u0027s members \u2014 one shared constant each site spreads or refers to, so the set is written once. Where they declare DIFFERENT members and only the form is shared \u2014 a decorator and its options, an annotation, a registration table\u0027s keys \u2014 the form is prescribed by a framework or a schema rather than copied, and the only collapse available is to generate the declarations from that schema; where you do not own the generator, this is the cost of the framework and there is nothing to extract. Check which of the two it is before acting: these copies still drift apart the first time only one of them is edited, which is why the repetition is reported, but the sentence to act on is not the same in both cases."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/KeybindingsHelp.vue"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d29e79471904b63e924c966f6d88bcd54ccd8fc2d193357de299f9aaeec9b2d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2 locations): resources/js/v7/views/ChangeLogs.vue:34 \u00B7 resources/js/v8/views/ChangeLogs.vue:29 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/ChangeLogs.vue"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"93c8de9be803bda026f8ec504d022f6a08679884cc19b18291bb95e713fad873"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (7 matched lines \u00D7 2 locations): resources/js/v7/views/admin/ContactMessages.vue:223 \u00B7 resources/js/v8/components/forms/contact/ContactMessageDeleteDialog.vue:56 \u2014 the two spans are one implementation copied and then locally edited \u2014 73 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/ContactMessages.vue"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"87a6323e6caaecb1898827fb4029644e4b736026aff2514f4f94b509b3eba804"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (7 matched lines \u00D7 2 locations): resources/js/v8/components/forms/contact/ContactMessageDeleteDialog.vue:39 \u00B7 resources/js/v8/components/forms/group/DeleteUserGroupDialog.vue:33 \u2014 the two spans are one implementation copied and then locally edited \u2014 57 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/contact/ContactMessageDeleteDialog.vue"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"f366690738523fd89bf53fa5d21ae31dca5f6fd3eec401de20b1b0e1e26695ce"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2 locations): resources/js/v8/components/forms/shop-management/PixelSizeFormDialog.vue:52 \u00B7 resources/js/v8/components/forms/shop-management/PrintSizeFormDialog.vue:58 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/shop-management/PixelSizeFormDialog.vue"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2b9f70181ce0c63fbf9c2574182092d6b7857e856d86cbd83a0e42c6be1113b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2 locations): resources/js/v8/components/insights/ExposureSection.vue:43 \u00B7 resources/js/v8/components/insights/FormatsSection.vue:86 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/ExposureSection.vue"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bc539a6b1197825d4f05f1de2994e4839c651563a665ad88ef2bb6bbadcb245"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2 locations): resources/js/v8/views/face-recog/FaceClusters.vue:542 \u00B7 resources/js/v8/views/face-recog/FaceClusters.vue:563 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/FaceClusters.vue"},"region":{"startLine":542}}}],"partialFingerprints":{"codehealthFindingId/v1":"369148a96adea6111df01da13b0a491c53a71b129860730df24c5aeeb21a7eb1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2 locations): resources/js/v8/views/gallery-panels/Map.vue:142 \u00B7 resources/js/v8/views/gallery-panels/Map.vue:182 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Map.vue"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"5798b8274df399f02a8525ff6b1efeee8e358a460e66d516aff8c0f1db3fafa1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3 locations): resources/js/composables/album/albumStatistics.ts:36 \u00B7 resources/js/composables/album/albumStatistics.ts:48 \u00B7 resources/js/composables/album/albumStatistics.ts:54 \u2014 all 3 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/albumStatistics.ts"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd61b3161bb26e78611a33e8b60038eaf69e188b20907b03b55c14fca36c072b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4 locations): resources/js/config/constants.ts:282 \u00B7 resources/js/config/constants.ts:290 \u00B7 resources/js/config/constants.ts:298 \u00B7 resources/js/config/constants.ts:310 \u2014 all 4 copies are in the same file, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/config/constants.ts"},"region":{"startLine":282}}}],"partialFingerprints":{"codehealthFindingId/v1":"978492035319a48705821a56b7c6ec10197f24a218e86c66f96308f86abbce2f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/config/constants.ts:307 \u00B7 resources/js/config/constants.ts:315 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/config/constants.ts"},"region":{"startLine":307}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ebe985b61c6bb0dd87bcf6615bdee1ed1121b0f8effae6b47a04796a4b55d26"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/layouts/useMasonry.ts:34 \u00B7 resources/js/layouts/useSquare.ts:33 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/useMasonry.ts"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c7ab417bbe78635c9f9d4b49061b7f5a3c581dfd9fea67cace50af2618e5b5e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 8 locations): resources/js/services/album-service.ts:285 \u00B7 resources/js/services/face-quick-naming-service.ts:21 \u00B7 resources/js/services/flow-service.ts:6 \u00B7 resources/js/services/init-service.ts:10 \u00B7 \u002B4 more site(s) not listed \u2014 the 8 copies are spread across 7 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/album-service.ts"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"5279051d9c42b0c2f1de82ffc1165933a1ad6fd8b1de47d5fbb9e69b97c4eb87"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/services/bulk-album-edit-service.ts:94 \u00B7 resources/js/services/renamer-service.ts:79 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/bulk-album-edit-service.ts"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3e3abeace1bdecc752785741a02a6e7fb1ed5a07ad9d299d04242192efa3f80"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/services/face-cluster-service.ts:14 \u00B7 resources/js/services/face-detection-service.ts:39 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/face-cluster-service.ts"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"3910aa7532e31fd38fcd67ab9005269208f6b5fbf1ee64a0526a4d64a60be751"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/services/face-detection-service.ts:6 \u00B7 resources/js/services/settings-service.ts:22 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/face-detection-service.ts"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a0539b8a2866e741f3f792a73625a5111afdee536f375dc725c74ede2eab499"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 7 locations): resources/js/services/flow-service.ts:6 \u00B7 resources/js/services/init-service.ts:10 \u00B7 resources/js/services/init-service.ts:28 \u00B7 resources/js/services/init-service.ts:38 \u00B7 \u002B3 more site(s) not listed \u2014 the 7 copies are spread across 4 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/flow-service.ts"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"3be2ebcfb47898975c05011fddc41759f6d8f87ef2195bec2a0730f2f5b09d32"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 11 locations): resources/js/services/import-service.ts:24 \u00B7 resources/js/services/landing-featured-item-service.ts:23 \u00B7 resources/js/services/landing-link-service.ts:29 \u00B7 resources/js/services/renamer-service.ts:60 \u00B7 \u002B7 more site(s) not listed \u2014 the 11 copies are spread across 8 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/import-service.ts"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"524802f63e090ba25eca7cb53acfbae67b8af15504f165d52da33c73e58d23b4"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 5 locations): resources/js/services/maintenance-service.ts:63 \u00B7 resources/js/services/oauth-service.ts:6 \u00B7 resources/js/services/sharing-service.ts:48 \u00B7 resources/js/services/shop-management-service.ts:82 \u00B7 \u002B1 more site(s) not listed \u2014 the 5 copies are spread across 4 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/maintenance-service.ts"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8a6f5f1815aad7fbe7a5cb5768d07ac399d33e6aa02934709c53d0efcc75205"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/services/photo-faces-service.ts:4 \u00B7 resources/js/services/photo-nsfw-detections-service.ts:4 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/photo-faces-service.ts"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"88cbc9a7abdd6395fb0a405ffa233a3ae644d4356eb8885ada633f6c63b6ed65"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/services/settings-service.ts:13 \u00B7 resources/js/services/sharing-service.ts:32 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/settings-service.ts"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"01481b257ef189f91d8c3a6e3528832c6ab62d60c8f007ff62b8f32cea6d7e0a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 7 locations): resources/js/services/sharing-service.ts:36 \u00B7 resources/js/services/shop-management-service.ts:70 \u00B7 resources/js/services/shop-management-service.ts:76 \u00B7 resources/js/services/shop-management-service.ts:90 \u00B7 \u002B3 more site(s) not listed \u2014 the 7 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/sharing-service.ts"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"628aa892781655247fc5dede6b9c7d0665dd2a8431fec42e308c7a20cd13e2d2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/stores/AlbumState.ts:315 \u00B7 resources/js/stores/AlbumState.ts:321 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumState.ts"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b1444e9833958883126a9e9ccda6b2269e6321a203be517a15bfc3b8dd96a1f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 24 locations): resources/js/v7/components/modals/faceRecog/BatchFaceAssignmentModal.vue:80 \u00B7 resources/js/v7/components/modals/faceRecog/FaceAssignmentModal.vue:123 \u00B7 resources/js/v7/components/modals/faceRecog/FaceAssignmentModal.vue:139 \u00B7 resources/js/v7/components/modals/faceRecog/MergePersonModal.vue:122 \u00B7 \u002B20 more site(s) not listed \u2014 the 16 copies are spread across 8 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/faceRecog/BatchFaceAssignmentModal.vue"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3f1a97003b63dd385330c580a3b8a2da857807fe1c5a78b3d8237aa022e64b5"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/v7/components/statistics/PunchCard.vue:87 \u00B7 resources/js/v7/components/statistics/PunchCard.vue:95 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/statistics/PunchCard.vue"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"82ef2fc9683ea10d4349031182f30da4aa427344fa48e3920da77aef6d0382bc"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/v7/components/webshop/TransactionIdLink.vue:23 \u00B7 resources/js/v8/components/webshop/TransactionIdLink.vue:25 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of MODULE-LEVEL DECLARATIONS \u2014 bindings the module declares and exports \u2014 rather than statements with a call site. Do not read this as an extract-a-helper row: a call expression cannot stand where a declaration was, and putting one there would delete the names themselves, which are what the rest of the codebase imports. What actually repeats here is the INITIALISER \u2014 the same expression shape written once per binding. So give that expression one name (a small helper the initialisers call, or a shared base value they are each derived from) and keep every binding under the name it already has. Where the run is an enumeration \u2014 one binding per distinct thing, differing precisely in the thing each one names \u2014 the repetition IS the enumeration and collapsing it would delete entries; consider instead whether the set belongs in one exported table the individual names are read out of. Reported because the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/TransactionIdLink.vue"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea78a4f6bd31c67a79be89400eaeca6c3112a1b31f8cb9f278391785c6dffa0c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 7 locations): resources/js/v7/views/admin/Users.vue:100 \u00B7 resources/js/v7/views/face-recog/FaceClusters.vue:251 \u00B7 resources/js/v7/views/face-recog/People.vue:94 \u00B7 resources/js/v7/views/face-recog/PersonDetail.vue:239 \u00B7 \u002B3 more site(s) not listed \u2014 the 7 copies are spread across 7 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Users.vue"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcfa446d6d74583fd544fc4f32f35ed64e8be0bad5877bc0bb3afad928e99d6e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/v7/views/gallery-panels/Album.vue:381 \u00B7 resources/js/v7/views/gallery-panels/Tag.vue:216 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Album.vue"},"region":{"startLine":381}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7e7875774191d96c152a2ad27abf5afdece0e3a56de7595345bcc5d6352eee5"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/v8/components/forms/album/AlbumProperties.vue:332 \u00B7 resources/js/v8/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue:265 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumProperties.vue"},"region":{"startLine":332}}}],"partialFingerprints":{"codehealthFindingId/v1":"d93790d84d5ede843a1ed2938ad622b10712a679d3d7dbb98eeedd264ad7f0f9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4 locations): resources/js/v8/components/insights/DevicesSection.vue:27 \u00B7 resources/js/v8/components/insights/ExposureSection.vue:43 \u00B7 resources/js/v8/components/insights/FormatsSection.vue:87 \u00B7 resources/js/v8/components/insights/RhythmSection.vue:31 \u2014 the 4 copies are spread across 4 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/DevicesSection.vue"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4dfa2764d267d0bc18e519f18c6940506f0946c9ad084d11d9ce41220ccd563"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/v8/views/Sharing.vue:248 \u00B7 resources/js/v8/views/admin/Settings.vue:177 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Sharing.vue"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e6e43b1d0a478b9d1ded62a48dd996dc1a08fe644f188fa351fb5c7d6458665"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4 locations): resources/js/v8/views/admin/LandingConfig.vue:801 \u00B7 resources/js/v8/views/admin/LandingConfig.vue:1022 \u00B7 resources/js/v8/views/admin/LandingConfig.vue:1126 \u00B7 resources/js/v8/views/admin/LandingConfig.vue:1155 \u2014 all 4 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/LandingConfig.vue"},"region":{"startLine":801}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f8db99345029d8a9a7fcd3ff90b7d50484d983a0f932f7481a4c43a2e1d1b51"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/v8/views/admin/LandingConfig.vue:1077 \u00B7 resources/js/v8/views/admin/LandingConfig.vue:1084 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/LandingConfig.vue"},"region":{"startLine":1077}}}],"partialFingerprints":{"codehealthFindingId/v1":"7beae4a94a78121da2a3c213933bfd9c3e27676802fa08a73931e81201c80e65"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): resources/js/v8/views/admin/LandingConfig.vue:1129 \u00B7 resources/js/v8/views/admin/LandingConfig.vue:1139 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/LandingConfig.vue"},"region":{"startLine":1129}}}],"partialFingerprints":{"codehealthFindingId/v1":"02af2fd266926bb049ac9f720ed9d47eddbbb4df6f485eab2f2a0bdd308155b9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2 locations): resources/js/services/album-service.ts:347 \u00B7 resources/js/services/photo-service.ts:27 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/album-service.ts"},"region":{"startLine":347}}}],"partialFingerprints":{"codehealthFindingId/v1":"30a7a4bd7d7725296a2c563b4c5bce3f14872fa2532b1dc0bbcab548535b58e6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 6 locations): resources/js/services/diagnostics-service.ts:25 \u00B7 resources/js/services/flow-service.ts:9 \u00B7 resources/js/services/init-service.ts:9 \u00B7 resources/js/services/init-service.ts:33 \u00B7 \u002B2 more site(s) not listed \u2014 the 6 copies are spread across 5 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/diagnostics-service.ts"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"e42fd4d1fdd5d50ad94fddbae78c71e848c3136de8a1110c2893796321a7862e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2 locations): resources/js/services/moderation-service.ts:11 \u00B7 resources/js/services/nsfw-findings-service.ts:12 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/moderation-service.ts"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"13b90535b9bf22976e06ec1610f2b3915df1fe4615ad0bab926f0ef3cecfb74e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4 locations): resources/js/services/people-service.ts:6 \u00B7 resources/js/services/webhook-service.ts:36 \u00B7 resources/js/services/webshop-service.ts:6 \u00B7 resources/js/services/webshop-service.ts:122 \u2014 the 4 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/people-service.ts"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"f46896f427537dbc9d72a5000d892813b1e52abff20c1fe576cb8b9f4a7f94a4"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2 locations): resources/js/services/shop-management-service.ts:93 \u00B7 resources/js/services/shop-management-service.ts:107 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/shop-management-service.ts"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"1da1fd0d31ed9cc949332055a4afb2b839bcf82aac3c9e6c7da1dc6a9f863ff9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2 locations): resources/js/services/upload-service.ts:14 \u00B7 resources/js/services/user-group-service.ts:4 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/upload-service.ts"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c320b6bdb5922b398a9691d77f68fa20d42729ee2b7f10031057729da845a6c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2 locations): resources/js/v7/views/Permissions.vue:45 \u00B7 resources/js/v8/views/Permissions.vue:45 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Permissions.vue"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"82756b84f8aefc6cd032e1ea75cd53e205b5d7b0d9af6dde84a5f63203ace9f7"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (5 matched lines \u00D7 2 locations): resources/js/v8/components/gallery/albumModule/thumbs/ThumbBadge.vue:20 \u00B7 resources/js/v8/components/gallery/photoModule/DockButton.vue:13 \u2014 the two spans are one implementation copied and then locally edited \u2014 67 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/ThumbBadge.vue"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a3199773da6af128747c63d26e76a2489e2fd61eccab19862b8c4687c833dfc"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: resources/js/services/sidebar-map.ts:3 imports leaflet.markercluster/dist/leaflet.markercluster.js, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/sidebar-map.ts"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"799a06d7b1bec44cb597f8f605314aa743c6bbec3dabd860ea351c88c986dd4b"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: resources/js/v7/views/gallery-panels/Map.vue:31 imports leaflet.markercluster/dist/leaflet.markercluster.js, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Map.vue"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"e62ce12f19c595356ff97ac51d6d65ffc6f9c8461bd133e04b2f7b637cab32ac"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: resources/js/v8/views/gallery-panels/Map.vue:33 imports leaflet.markercluster/dist/leaflet.markercluster.js, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Map.vue"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"91e05b6ac2f51aa6e89ccfa66fb561b917590d74854779e69da574082672302a"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function phpDateFormat (cyclomatic 56, cognitive 35): phpDateFormat has cyclomatic complexity 56 and cognitive complexity 35; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/phpDateFormat.ts"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"b50fb91b3fad2c907d36b982f691ce11bf82fee8379deb0209a1d7a8ec021fa5"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 48, cognitive 47): (anonymous) has cyclomatic complexity 48 and cognitive complexity 47; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a7b52e1847e77c0e326aa7efe41653bd283e2d124beab5e0f4bf024c3dd7e08"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 40, cognitive 13): (anonymous) has cyclomatic complexity 40 and cognitive complexity 13; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/LandingConfig.vue"},"region":{"startLine":673}}}],"partialFingerprints":{"codehealthFindingId/v1":"93f4c6f5e39f0d531e056d61749d083b7350308b153ac600bf624e057e2f7faa"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function mergePhotoDetail (cyclomatic 38, cognitive 35): mergePhotoDetail has cyclomatic complexity 38 and cognitive complexity 35; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/adaptPhotoTile.ts"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a4d78edf51c28d2da9694e53d1f954165f9634ba5b518b0ead8afe648fa9751"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 38, cognitive 24): (anonymous) has cyclomatic complexity 38 and cognitive complexity 24; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/spotlight/useSpotlightGalleryActions.ts"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"820573b853bdd3423a9ea49957d06898ca6577634bda76110f8aadf1193841f7"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function validateConfig (cyclomatic 36, cognitive 35): validateConfig has cyclomatic complexity 36 and cognitive complexity 35; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/config.ts"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d087b0d28c37a1d332f8da15bf2e38914bc7f78f601e88ad57bdc7acb044aac"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function photoMenu (cyclomatic 35, cognitive 35): photoMenu has cyclomatic complexity 35 and cognitive complexity 35; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"26604ff19c8ee1e485196716235ca4af920fa9237f8303086e4d858ad07fe5bd"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function photoMenu (cyclomatic 35, cognitive 35): photoMenu has cyclomatic complexity 35 and cognitive complexity 35; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/contextMenu.ts"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"877538f51499bd469d26a7630b9b3bedc18310d1758e6f74772b53f668576ec2"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function parseDataAttributes (cyclomatic 28, cognitive 34): parseDataAttributes has cyclomatic complexity 28 and cognitive complexity 34; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/config.ts"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"acdd73d7e3ebb5b6a1a2b9b9f868b6d9bd74b73846edf9b4f10a4da797f31851"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function parse (cyclomatic 26, cognitive 45): parse has cyclomatic complexity 26 and cognitive complexity 45; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/utils/sprintf.ts"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"83955420c4248c218bd817832e4913877c8e987fb2b7718c649f2d91d868f976"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 26, cognitive 25): (anonymous) has cyclomatic complexity 26 and cognitive complexity 25; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/leftMenu.ts"},"region":{"startLine":169}}}],"partialFingerprints":{"codehealthFindingId/v1":"4597283dd7c4491e6eb32e023e91aeae09651b579a0e8f398c806edc0c131647"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 25, cognitive 19): (anonymous) has cyclomatic complexity 25 and cognitive complexity 19; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/AlbumsHeader.vue"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e0ad3bb7e6446d9346ba99d1163af06b36ad7f32c7642001b5cb5caee4b4b56"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function decideKey (cyclomatic 24, cognitive 27): decideKey has cyclomatic complexity 24 and cognitive complexity 27; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/quickNaming.ts"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6a65499cfafcfcb028f0c44356744583705573ac5ab894edf7049a0bbbdc72a"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 24, cognitive 24): (anonymous) has cyclomatic complexity 24 and cognitive complexity 24; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":513}}}],"partialFingerprints":{"codehealthFindingId/v1":"b71b3116c8c74502535cbced2e23e3bfe7497645c34700b2d0c1a3235bdd02d1"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 24, cognitive 18): (anonymous) has cyclomatic complexity 24 and cognitive complexity 18; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/AlbumsHeader.vue"},"region":{"startLine":271}}}],"partialFingerprints":{"codehealthFindingId/v1":"40219d50d756fdfccfe2eecea994c9c7e94f5c049dd3516761ebdd7e0105ef10"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function photosMenu (cyclomatic 23, cognitive 22): photosMenu has cyclomatic complexity 23 and cognitive complexity 22; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f4518309c6d29b04e5532a6800c584569ccbfe5d6e977a49215ad7abc526d90"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function photosMenu (cyclomatic 23, cognitive 22): photosMenu has cyclomatic complexity 23 and cognitive complexity 22; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/contextMenu.ts"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"de51ea17817fd9cfa4d1029440facaac366e5c11c20b28529f684db65140efb5"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 22, cognitive 38): (anonymous) has cyclomatic complexity 22 and cognitive complexity 38; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/timelineModule/TimelineDatesV3.vue"},"region":{"startLine":319}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d7e67d8bc0b94bc0f29b07a07598afcb9bd4804aaf20f93901dfa1b356efe51"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 21, cognitive 15): (anonymous) has cyclomatic complexity 21 and cognitive complexity 15; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/config/axios-config.ts"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"a88dd2907ff84491ef1dd90e911b7f8464ec4fdb237a9f296f76696bb1d31b1d"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/views/admin/LandingConfig.vue: 1124 lines of code: resources/js/v8/views/admin/LandingConfig.vue has 1124 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/LandingConfig.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"01cb98ccaa25295102989d6cd4d01ed63d9918cee9a2b2d91424388982d3d5e4"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/stores/AlbumState.ts: 963 lines of code: resources/js/stores/AlbumState.ts has 963 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6668434fc960958bedb9167460d59b78bc5694750156da32146622cf92d767a"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/views/face-recog/FaceClusters.vue: 775 lines of code: resources/js/v8/views/face-recog/FaceClusters.vue has 775 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/FaceClusters.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4375586cf6099687bb121f9cd401f9a0b0b42f8dd44f83cb3121d53e9dad5764"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/views/gallery-panels/Map.vue: 737 lines of code: resources/js/v8/views/gallery-panels/Map.vue has 737 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Map.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"13d43da2a5c76c731c26071175ea8d10f847f873d447d26ad04b27673cbd13d4"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/components/gallery/albumModule/Virtualized/PhotoGridVirtual.vue: 701 lines of code: resources/js/v8/components/gallery/albumModule/Virtualized/PhotoGridVirtual.vue has 701 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/PhotoGridVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a4374e59438e4162680cc7972cbbc828082675898d2a34f69820ad5e48d45a3"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/components/gallery/albumModule/AlbumPanel.vue: 682 lines of code: resources/js/v8/components/gallery/albumModule/AlbumPanel.vue has 682 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bef0e6d0ada2c49bfc48aece99857a86c1b7254008159925900e3b92f29b0fe9"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/components/forms/album/AlbumProperties.vue: 629 lines of code: resources/js/v7/components/forms/album/AlbumProperties.vue has 629 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumProperties.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2ff45d1b23d8f9cf69b48b559175356cf061997ba7d4559c36e0f65d5d6f0d7"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/views/face-recog/PersonDetail.vue: 626 lines of code: resources/js/v8/views/face-recog/PersonDetail.vue has 626 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/PersonDetail.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9ccd899d761e97f321d3146435c70e6f108a100943d2a4c2087191a8b63054e"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/views/gallery-panels/Search.vue: 622 lines of code: resources/js/v8/views/gallery-panels/Search.vue has 622 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Search.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"49a22c72a45556354f32c548eae839023913b3673102ae3b0032dcbde8bbb492"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/views/BulkAlbumEdit.vue: 620 lines of code: resources/js/v8/views/BulkAlbumEdit.vue has 620 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/BulkAlbumEdit.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7300908eeb7525404ba542b9fd9eab551b2e749a8514deb9820d4cb06b5d326c"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/views/gallery-panels/Timeline.vue: 619 lines of code: resources/js/v8/views/gallery-panels/Timeline.vue has 619 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Timeline.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d7e0ddbc63301e326abb3f99b999f6f3fe9bdeeb1ce60e4033e1a6b33199697"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/embed/components/EmbedWidget.vue: 605 lines of code: resources/js/embed/components/EmbedWidget.vue has 605 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/components/EmbedWidget.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"183bcaa2c33dda354de3f375215aa1b8dc06d1e76feeb7efed794358f747376d"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/components/forms/album/AlbumProperties.vue: 603 lines of code: resources/js/v8/components/forms/album/AlbumProperties.vue has 603 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumProperties.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"579e1a8cfe703635b3a7819dc3eaddc3be0587048c3b460a5cd20aa5a62c341e"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/views/face-recog/PersonDetail.vue: 598 lines of code: resources/js/v7/views/face-recog/PersonDetail.vue has 598 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/PersonDetail.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e21328160d4fd68ad49da68ec51301a8de02bb5497b001666dec737a748a26f"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/views/BulkAlbumEdit.vue: 576 lines of code: resources/js/v7/views/BulkAlbumEdit.vue has 576 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"294eda458904aa6bae83483de4b2fc4eed286b7011cf129eec27442fe08e2508"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/views/gallery-panels/Search.vue: 569 lines of code: resources/js/v7/views/gallery-panels/Search.vue has 569 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Search.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"172a36c3c6fb787c0444919e17a731648af32a01d31ba0602a35dc43aba9d677"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/components/gallery/photoModule/PhotoBox.vue: 563 lines of code: resources/js/v8/components/gallery/photoModule/PhotoBox.vue has 563 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoBox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8247a6a0beb208f13776a3074cfac5d4b41f99991587bd9b62f76ea69c8c68f"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/views/face-recog/FaceClusters.vue: 555 lines of code: resources/js/v7/views/face-recog/FaceClusters.vue has 555 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"be073b8aab606d4e4bcf9eff523e7a050c59e636140275dcc6dd780b982155e4"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/views/face-recog/FaceMaintenance.vue: 543 lines of code: resources/js/v8/views/face-recog/FaceMaintenance.vue has 543 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/FaceMaintenance.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d6f1c19e8ab4189266900f571b37e77bdfa82797860eef272f625c9e05767dd"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/composables/useSphereViewer.ts: 537 lines of code: resources/js/v8/composables/useSphereViewer.ts has 537 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useSphereViewer.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"47354d4ceaf7dfbbe9bed0567f3e24af0a1d8b5846d1b1c54327e3058cc4ed4e"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/components/gallery/albumModule/AlbumPanel.vue: 532 lines of code: resources/js/v7/components/gallery/albumModule/AlbumPanel.vue has 532 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"39e8a5489dde178c8dd3238862d4cf412c474a31f5ce65e5fad43f3a66c5eeb0"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/embed/components/Lightbox.vue: 524 lines of code: resources/js/embed/components/Lightbox.vue has 524 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/components/Lightbox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc8cab18531cd725939daf73cf3ba65bf63164c4da4a4985bc3f1a72125afb15"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/views/gallery-panels/Album.vue: 520 lines of code: resources/js/v7/views/gallery-panels/Album.vue has 520 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Album.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb3e668c8e494935055297aa5194c2768ff03eb88515e028b06d5867130f7ad4"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/views/face-recog/FaceMaintenance.vue: 515 lines of code: resources/js/v7/views/face-recog/FaceMaintenance.vue has 515 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceMaintenance.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"09f1beb716deafb8ed594875be0575f2008bdfa79718dd64063a184c24880d89"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/views/gallery-panels/Album.vue: 514 lines of code: resources/js/v8/views/gallery-panels/Album.vue has 514 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Album.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"11ba61b30a634cd40810fca59781359b4f86fcdc13051deb6474c79274e34d07"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/views/gallery-panels/Albums.vue: 513 lines of code: resources/js/v8/views/gallery-panels/Albums.vue has 513 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Albums.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"295be95ef2e27f756e544791eac49a5d9cb89277f6518434aedc5fff502d4142"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/views/admin/WatermarkPreview.vue: 506 lines of code: resources/js/v8/views/admin/WatermarkPreview.vue has 506 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f766a21398060300e770ec654ec7c1adc81d8578604da338e6140d35ca219113"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/composables/album/dragAndSelect.ts: 504 lines of code: resources/js/composables/album/dragAndSelect.ts has 504 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/dragAndSelect.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5faa551bcb3e8f70269de6bc1275a2238b0ead1d34c443c63fd2158a51bc7992"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/views/admin/NsfwConfig.vue: 486 lines of code: resources/js/v7/views/admin/NsfwConfig.vue has 486 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c452eea02cc093d75790bdb0846873118454a64518ce9442a29fe8ad0982e52c"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/views/gallery-panels/Timeline.vue: 481 lines of code: resources/js/v7/views/gallery-panels/Timeline.vue has 481 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Timeline.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1842f9a24e283e9b246398264a820534d4663275dc8eb50d8273eacc2b013578"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/components/gallery/timelineModule/TimelineDatesV3.vue: 467 lines of code: resources/js/v8/components/gallery/timelineModule/TimelineDatesV3.vue has 467 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/timelineModule/TimelineDatesV3.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fa9ec9ab018b12aa4716e8ad0386535d933549400a258957dc78d4746189d4b"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/composables/contextMenus/contextMenu.ts: 459 lines of code: resources/js/v8/composables/contextMenus/contextMenu.ts has 459 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/contextMenu.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e59ddbb914efa8e79370d1feb238756ff76c5ab3e8868ec4e35f3859718b7bcd"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/utils/phpDateFormat.ts: 459 lines of code: resources/js/v8/utils/phpDateFormat.ts has 459 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/phpDateFormat.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad61463eb8e27bb1627d0d286598030826ee125c3b715d1558083cbe045f4ca4"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/composables/contextMenus/contextMenu.ts: 456 lines of code: resources/js/composables/contextMenus/contextMenu.ts has 456 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae5558b4d13ab7e220e868bc8094585b934cce10b6bd8cda505278ecd0b05244"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/views/admin/NsfwConfig.vue: 452 lines of code: resources/js/v8/views/admin/NsfwConfig.vue has 452 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/NsfwConfig.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4f5db51326ef15336d5cc91c014e2b73eb964ba10b732f66d97845c7c0f5623"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/views/gallery-panels/Albums.vue: 450 lines of code: resources/js/v7/views/gallery-panels/Albums.vue has 450 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Albums.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"46702ac3263b6049d7e59267dcf067da34bf06fd0e3ddb3712964ac0b1d04265"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/components/settings/General.vue: 442 lines of code: resources/js/v8/components/settings/General.vue has 442 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5653a31ff36fe0f875be018ee2fdc1488f3c7fd535051e0b5d95507904d747e8"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/components/drawers/PhotoDetails.vue: 439 lines of code: resources/js/v7/components/drawers/PhotoDetails.vue has 439 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/PhotoDetails.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"74b1a8538ddf922878ccdb2990175b4d5879b2127093f5273f95252e7409b987"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v8/components/drawers/PhotoDetails.vue: 420 lines of code: resources/js/v8/components/drawers/PhotoDetails.vue has 420 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoDetails.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f87deb62a24b9786069351636b542cd0235005efcee0f78b2ab0786b0cdc137a"}},{"ruleId":"R3","level":"warning","message":{"text":"resources/js/v7/components/settings/General.vue: 417 lines of code: resources/js/v7/components/settings/General.vue has 417 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3fe46aa5ad3666102728bf9bee58cfc34fc3380fc5fea35a3c4d02dc7d8bc3b5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/LandingConfig.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"411c4f2607f592a62a9721ebbaf25c932e39d18eaa9fc6c826066ef108186261"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/style/preset.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"934b515a3b940e2b7bd7e576e490378127fa9819a320d87a9875f4a6cd036822"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/FaceClusters.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"908ef2a597b57bdce90680dac7a8c3cee266c3903935f248fe89c5617859805a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/PhotoGridVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"975a2e068c3388683ea5fc44724f2b370f8107969e56e66e33fdf190c77e8cc4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Map.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"583f838a869bc57127415d0fb0012675ab595db169e208ef45606c88e26c9dd2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"17c087540e84fbcbfaa0ec131aff012778484481fdcebeff2720e6660eb6bfca"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/PersonDetail.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf8c75a0dac213db82fb760b31969b0106964426df04bc3254cbd7f13dc241c5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Search.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4d594e7cbd1a8a6583a85e89345f93ef2b424bcc0e9a263e6f71dfe9508e790"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/BulkAlbumEdit.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9b6e048edd5d688860f6fe6a88b73ac8c08ebacb4fe5ed780e4c653bfe523e9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Timeline.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a5d45f05672249f540d6adcc9bc34e73195abc981c5465ae4321363e12c78d0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/PersonDetail.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"01e14c6c3bc5c42e4e5a45bde5dad22c63bbe010269f5ae9b20fe4cda12f9eb6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumProperties.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"01d1ad9f2583f3220d0c7d8d0205e7001f62c866c69b555dfb047b5e84fd34d6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/BulkAlbumEdit.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"50da4362ccc463451e6cf1fdd4ce39966d3f240b719040d5ad1d626fe0d0b209"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumProperties.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b769f4bc6126f1d442cea861cd771a2fb19d7ae3b9c2baa57eaf6c1f3a8589d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Search.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2899722df0d135569286874e52b3d37297eaac6db6d4b74a0cd82a44b543cc1e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoBox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8384d7de1628d0acba7cc4a2c1dcc8bdf96e954bade4d8c402fed9583196cee"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cea59e4ae117c0800cdd878416835ec26533d64eda1d4601757f578a0cfd2e90"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useSphereViewer.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7895665b69941d23b826316a5ab270d064955c9f3ce7a40b7a1a29084f72201d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/FaceMaintenance.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e358fcd051ae8e83754f6c78b80a17afa792ac9560fa0bed18e356a37f2aa57"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Album.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"896e6bea061ec26e16695e4735b866ce9b93e8d03be09b5d651fbd38e6c521da"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Album.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"75590a27f45ab185480d030e400a3e2ac25947847cb1bc6be2a18282de891d16"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/dragAndSelect.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f367e8d54fe126814fa43b8e363414a89f6fd649fa795b02e30a4fc54e05afb8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceMaintenance.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1ff3a898cce3ebc608bf5e5da5a865dad9733f07935d5de92c92b363b520082"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd27a2aeeb078bc1cfbd4a6d8c5083f01bb0f3decc2e9f5967a520a50fd45c3d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Albums.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd16e66efcf3cb973ddb7243852cf2da582660f2fb12a4624ef9b7fb6132e0ba"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/WatermarkPreview.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d2fd17243f860c4ef6f4815d0af77ac1ce7d55c1900927409b7f271ec2b1692"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Timeline.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"705e5f6ad1731076798cb2f8dd7164f9d635551b8a6b8a4e3402c06ed262b5cf"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a705342850a902733648d054b6db5a1918ed13d5873047af83730674f3d3aa66"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/timelineModule/TimelineDatesV3.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1d70b9a3ab0a45a7ecc4a3b4af9abe0e2627854592f89856d450acad5b03fa0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/NsfwConfig.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec66b5bf1951110744a0834c3a0f664ed73ae05a114ffe181d5d1f3f41c7843b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Albums.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cda353e4afb9f56bd8f0690ac1333eaefff740c6dd094a1c2b7c6cdd9f54b22d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/PhotoDetails.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"996f905d44791b4fba00846238bf46aa5073695f8688e791bb34150baeb1de2f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3deedb03efb55c593dd067dbf95bf731e879d7c1e3a64f2a6d6736f05261ed1c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoDetails.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e767a2b9ff4f4b3ffe8830a5367ddbff6a93ee425f1953aa73e4d33f740c869d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"aacf65c5a6f5ae42256ebe7b7b41c39fbfc10d7ebc85a33c6c1041bc32e244e1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/EmbedCodeDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8c5e85af23b5baebbd17110b72fc0eb40b3ec491c59e1f92933e4ccf30551fd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/TimelineState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c5ef05314f753dceeabc6a617cb319c17fc4d337677c8c3c193894107a0b1ca"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/usePanZoom.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8da3a23e55a9562a32d3f232d85ad10cab4c06f713d7fb9a65243a101fb94119"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/components/EmbedWidget.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ce9106abbbc550d944956f9922000d351d080ed6c103451e7f1b5e14467b484"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/photo/analyticPhotoLayout.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"231e864755cff34e385484b6a1933f55ee83676781a5a4c2ed684674d332b76e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/EmbedCodeDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8348b7736c5aa876863ef85f6dedc7785b6efb3894cfdec2e52fe7bee042442a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Flow.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8528d75cdaf3a9ac4ddcc1f941e0dd992f32a970372bdbc401f32cfbe0b53e6b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fec2aba896afa01ee5cdd1bec415f6551510a3ab2375d8ea4485672a4b555a8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useQuickNamingSession.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"29a125febee13cafbb9ccdb144f50e35169277d67aa0b333eec34569d2cecfb8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"df7442d3c58f6333aac7adb276a6043c01f6fd8aec22658650ab026e51cc9a5c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/utils/sprintf.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"08f04b4a40157da20156199165970c695e5cc8c7c0365e8541e8eb7f745dc194"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/FaceQuickNaming.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5dcecf016a99c2de82217d72b68a8b6697904d2683b195217f4982da461ad65e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/AlbumsHeader.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3363905abb6c1d894fdf25b96d9323895f85a8b92829568971085f85be7c8c20"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/AlbumsHeader.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fa03d862410ef4c68d77a0ea7b88e82c9852b7936fda4370708a7f531c5fa4a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/components/Lightbox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bfd460baca1772388011362e0d3d0c02a07754a028ffc41415015f67199cd50"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0a86f935483dc00efe569196fd1694a36a3ec0b090ebd9f866ccc6e2a81f8a8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/renamer/RenamerRuleModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"64d9d3cb1caf089f2b64191814091d1ee7ed6981ca96bbd47a24d8e7bc1ea263"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Tag.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eed884625e23a2bd4c57d62d0612972a0a2844433095a559beb95bfd857fd11e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/AlbumEdit.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bf6bb797cb01008563c02526188536aa6bf1ad0f59c473f78e6cafd7468ad8f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/SearchState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"59f0b0609afb6dae60cb9afc085a806be04e8245291d2f087b55fa579dc6de4f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/webshop/OrderDownload.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cd177361a371371f9bc597581949cfd3abd899739bdb6e3d4eabf1d476466f2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderDownload.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e8562ccf68e470e69d02de5d0f4b4256b9a66c2b559bbe5c6b2ac18a06b6353"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/NsfwFindings.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"712cfdf3858d4ce9db35fd017225bf1cde085421cb9caa4fcfe4291f8e736034"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/AdvancedSearchPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"81f76fab6f7cf929be2a2933df7d8a9092546f02bb5b5b36403d4b83095036ae"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/LiveMetrics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"245027c7dea34bbbae1701e1f5eab5672802b5b4ec6061c7493c501c440fa31c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/renamer/RenamerRuleModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"64625b1baedee08280ef93e100c9eaa0432f44a3849d81a555ed782db9b2c128"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/leftMenu.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b3e6985ecef72762d7c0979097ac7aaea28b1ac3091e728ebc47a1454e2c697"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/selections/selections.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"76db08c116e5fcfae94ddd0f8e1b4106ce5561fb2ff8dc1a9adb65d3b5bf38d7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHeaderPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea5a3f84a1e122c3018ac56f886242600c46b2a739cd363f20a5e9866ccc6e01"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Tag.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f09636fd3644a5caace6508fbb80f8fd9b382ec8f2318559429b98e09a6a924c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/bulk-album-edit/BulkEditFieldsDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e95966ce095e06c2541e6e8ab159eec273b5918256adc7ff46489bc2484160c3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/Moderation.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7285a28ff5bc578f75ead576e8074fc2a6f481127ee52caf8123d46dd3ed222c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumHeaderPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd143aa4d945eb4a1c408f16e9ada2a59e94711b8e059de8222e8a38c1fdc072"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/UploadPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e80aa64d45c0db713893d63ed765b60afff9df6832aadd5317c923589c0fc8c0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8768b9e7718f1532f234080be16d82917d1d481014fddac4526f465d7254c253"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/treeOperations.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f3804c92eab72039b61156e19f9b41a1255f3be72ebac614db8c706b6f1867a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/AdminDashboard.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad75c1905a5317fe529201c04f7bd4e4606349af9e8979d53425ec8ccdbac0c7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Map.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"948a2257bb1d99a0d56c85a0ec5e1bf14c90614b5d606d3d67ba5ed20fcda4ea"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/DesignSystem.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"96b8003805fab391484dab45fef00d654aec435d47c0148fc29cfcea998d695f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"13c383fd28c6d10f7a1b629b04b96bbb42a0195e05b328d278070b3ff6ea77b9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/ConfigGroup.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ba789358ce38c6b1e2c2b5df97fba229f4bef1ae9988b4d79d0e3c13a9b85af"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/PhotoState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3564c9affd889a58a9fe0ae72f3e0b80db5c9f1e4f7c3b0e813e783ba0953b5b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Moderation.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"14beacc4728f19519d32ccbe2783261621c0d934181ea70a5caea89f5201da02"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/TimelineHeader.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"12920101b21e947e1b41f225d4ddabc5286c8005e4986fdab2088472a2cb42ff"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/albumTileWidth.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ac7305cca6afb198e8042fbc6fc5ee722cb2c3941d94c125fea68e3b1e8195e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/Users.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c17562fd3d894e925fcd1de323c870a2c35afda5348d0b5eb33ce7de9575bb6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/People.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"93945cc266aab4064642ca56ea85892c7020e791a9ac4b0acb799b0b4fae18dd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/ApplyRenamerDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d0739cced8d77c2ef9b8d5458cf9e21b90b42672b810559eb4615d6d5dc9bdb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/TimelineHeader.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fff476be7b4a7fe3ce6c2a3d17517d0668fc40d4e559094cef8d71d7b35bc404"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/CheckoutPage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6420f5b028baae953e20a98ec69e14b83de75691cf3a24a2acda3166e4ca681"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/FixTree.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e411e2c9daa582764d7a8e1d2cea81affe862a6530b60350bb06b0b8a315f088"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoBox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5e34f0155dfff12739185133007ef6b2c3c5fbbd6c816c775329ddabe0a4050"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/panZoom.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"447bcfdcd02c46751caf782e285d30602cb8a10e269e89ab718f3126f8fd9474"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/railTicks.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e905f8ada6ad3af0283ceb012c9c13e12898c99b5d1a759633b5b898df926592"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbGridVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed7d1752c9ca858e30b7d26d7a96ac97a095f6628811d13fe40366c6d580ed13"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Sharing.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3671f33d7ab3976d73a59883a2490a96f98a09a8f0816ecea8dcaa8d79418a79"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/UploadPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"838ce76f3f8e63be22214dfd288797972f8ead95f0c761c48b35f3466768c1f7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Insights.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e0542e85578eb429da1dd9b9f3a83b481264689fbfab78f2d46545e10ce3116"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/upload/UploadingLine.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"82f133c7400c9b2d1f32865ea06b45286bab4ffc90d49c111401a063559e79f0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/RenamerRules.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"14a4da7b994b24c787d088b20f41c46275d32e8404af33419149840231b26346"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useAdminTiles.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"19096ded4b106379afee7ca38fb2b9719355983997afa23fb48c706e4eeda1e1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/PhotoThumb.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed1d2967daed6f1ffb6eabbc0f2c618d16dc656e3e44aa94e62eb221ff3d89bd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/LiveMetrics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a34c47305776d357cc3b63e5d4f14c038b2f8660cf931021132469861105b2c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/ConfigGroup.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0aa155b756913fd600a6a9d3a0c5ad90f052112dc7fb6d9ca33cdc38af8a4f18"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/AdminDashboard.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"22fe7bb40d961d298dab2a173ddf131ec28f88962e7b32e0f8418334966ead43"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/UserGroups.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8968b5609ab84eb11e627eade0edd207e7a9afcfb3865e572c7dba8ac56a8a79"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Contact.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9831010da8b7a7e112f3c7493136fb44bc5c169357ede336365fef4c07ba89e0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/PhotoThumbVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"29d28a51d861881190d98ccb7f1c78ade5cea7f0445ca1feb0ac152a91dca02a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/webshop/CheckoutPage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"38c93b65c84768c427ee0075727e5d73659c0d1b4ac32e7be551811e2ec24dd5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/SpotlightSearch.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"19df6a3d305e546fc86afc8a8705356abc2dcaa603abe8357f242e813580362b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/RenamerRules.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c499317ef05f097c916147728d679efdbe5a1a263ef341680a296d17030ed961"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoEdit.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f2bf0fce932fb92f196b57164c3d70ff0eee8edb5cca2c50fc489b1cfd5dc5c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/People.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8536c8663e5848ee664ae3b6dd9df05265f5ae1e37957da7a87cd578ee8d6a8d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/Settings.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"73d9d737b2e2495f160318405f34a942cc568a98a74cb0e724909a851767f449"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/MapState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a928922f36455f1c9ec0b69fb340179f46324d227794638aec941254f52abe11"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/ContactMessages.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0de6d90351f90bb09e8b297d713bf9c491e5bd6c9261106843f51b58e0d925c9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/users/CreateEditUser.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e157395395b3937619369c9528eb94339c3d090b8732be18864593b143bd7640"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/buyMeActions.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"338ea2a233b39f0fe6c78aec56279738b1cfe534d30827b44f13d6ced7c8e540"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/webhooks/WebhookFormDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"11e08fea7cf7afdb393d6c691c276430e1d40741e6e043a38bf1598aae3753b7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/users/CreateEditUser.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a41b9e696bef54b221b4ae4205ad418d6c274ae7aeac1adb1ec372e473a34ae8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/spotlight/useSpotlightGalleryActions.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b0d5bf14b6e66da47b90b8355b747667615d6f49a5049a44ce2476b5edd1ee6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/config.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a4845ec7e44e8132b17235768e129c9e8d51c2f98d389f251e0a83224b8a3f0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/webhooks/WebhookFormDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c637d8fc946c220eebe2451c5cc85de6e4a82f2541100561a24d38c414a2c936"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/ImportFromServer.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f0340418b010f13f673c780aec7e53923a9b086dc5ecaa76dced4c0ab08cbbe"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/dateScrubber.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc8ee663877b9e377dc2558a6d019ee30b66bce66478db4d4eea2f99c36bea5f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/Jobs.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f29ca5ade0c3a22f4d6149a6fb1d1c38fbb63a4e951058456df261e0f3006ca2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/contact/ContactForm.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f95d9b0e7cfb82759451a05cfc9613f8df05e2a4e4b135ccf89280a74097bd0b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Settings.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"849500b876a18e239fa1f8a2718e0da1d616945976908aeda767a56e13d53376"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootGridVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c453c1245242663d4829d3c97456c2515157efd7dc9facc07a1def41f40c932"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/api.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"20dd60c9158b7b1226efdd0e52150e76e5208e4746d9e468c4789d0753e9794a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/ApplyRenamerDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd20c8798d61f994c3552f66202885d54736f8df29d5e80b7024997c65ffbab6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/ContactMessages.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a78efdcd351883653d53a413710b40300be51170beba849cfc4b60a089f7d10d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/UserGroups.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ffbe690c1b9d8596ab668898e5d5ad8046a3f603826e4cae925e38ca2b358c9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/PhotoEdit.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a46159747bb12f62f5dd36642836a0207aee19cb08a6884586ab6468a782ef5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/FlowState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b23404a9a65275c1020cd0d63560c62c7273f4e88ba52fbacb0b668f11d40a7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/sphere.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1567da97b2489e6b99415d2970911f6f880ed56ef3985a29e9ff69156d7807c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/menus/LeftMenu.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"04a842cdb94b1ed3fb8135c53990d9477c3409ab5e04eb98a661e8b972519cad"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/sharing/BulkSharingModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d489b2c5151259668d41057568bf547b8f07ccadd913929754ab2bd6e100fbc"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/menus/LeftMenu.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"10f4f3d3039d3bbe777e3bf8d59aa6018a4c9a8328191c5db66a5fd632638130"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/CameraCapture.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"29c5fe5f605a973836888ab08a43ffa5169bab7d74b94523cdb1f4f844595891"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/Password.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"182c9d72f045dcf27121fc6a58a1062cb7b29adcfdf100c540596cb7c277834a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useSearchTokenAssembler.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3203c7c8a8ccdb5d08d2c9ddab5f90b76d6720c724c26d9217470220ef5ff61f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/PhotoThumb.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0e502be729c15f6481b15bbcd2130ac832519de7200ce13c291e97a4ea2d9a5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/gallery-dialogs/MoveDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"45bdc721d407c3b3a3a977d00681c8f2b515598715ff71f91eb256360914fa17"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/utils/columns.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3c1879cc1e1c6c2a92e292159af34a8f29dff0a06d110284cc408c667244a4f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/ImportFromServer.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ca49b61e42334daaa165923320466a35f64cd8dddcf7914c069ff6f5dd01c04"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/insights/options/timeline.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4aef5111442c05d6ebe59cd42e47fab15357880efc8c737381b5e0dc4e294d76"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumPurchasable.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5781c5295f8ed2d53e12c568182a982cd66e65581ffb14ef9c0aaadfa6d9b2e0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/preview/getPreviewInfo.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"874c6d2ad9b80ddf08080b764558c321e3d26dcc5bea81c8c36ec579b6df5780"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumPurchasable.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7098af45365977e7ba0850618a8d370530752e5722f6cd8c397287872cd20789"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/upload/UploadingLine.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc28438229895f3b20c95371045b5bf7e30322a4fb8eb189a36add9bf7a8d683"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/CameraCapture.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f5a25968f9e37c19b1dd48a8f05f0026a659f2b98eafda69daa014aa006128f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/DuplicatesFinder.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2accbc98bafbe8d7be6c157cf3523a75090793996f16ff55589034fc45bf746d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListViewVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f347fbb2b4b47fd4b3f15070cb0ad870cd8066ba1b421b9b05ec37b571cd78e5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useAdminTiles.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5dd5328b0d7daf4c4c86069290fb776f7c260f36ec53d3fba6da82de8745f356"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/auth/LoginForm.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc7e5c0d088786239a3208a79ec0827e81bf14e3b6ac12b4e197110213620c55"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Flow.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"21e98b63745b8dd38c0764a8f07370947a70a737d21734a02e9e6896511507bd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/searchModule/ResultPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc4eda4350f516731eff90039e0191acfa51790f0dc22911889e138c41221bdd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/gallery-dialogs/MoveDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"565fbb875d7b408e668839c61143913afc270b326e3a00089a6d610a0ff65d68"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/AlbumHeader.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"270c4ac0452623568d63fb7a4cc036ca91ca9b5357b9a3bedfec4f2e4cea5953"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/PhotoHeader.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"da3c14c5a5652a59be8761f8bcee6275a76f5ac84e3a1d6979b52e419cebdeb6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumVisibility.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0a4eace2e3d5960eb87738213b20a9ed3d943274503db1139a62f5dd1a14551"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumListState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff102642be54619d69714ce8b5aa412af21a2d556c6e33df1efa996a6343a32c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/pagination/PaginationInfiniteScroll.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c2c5c70169e9a74ad5ebe4b804e1a451740d1b521a1e5d1fa1620b595053d69"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootListViewVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"efea26c2f3da1327991522cc39c99b8c07a8f9146e6270a1329a4177c7b716d4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/AlbumCardV3.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a470b13424cf92f90a3b0cbd910bbb173f25d9defa89a548bd2762840e2c2e6c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/DownloadAlbum.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4505fe60baa9df482de2bf004d672c27b5b664274fd9cad6fa256f350903726d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/KeybindingsHelp.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"97ea0b4292fda99c1ac060f2b78e437b0d14584dc4db1b2f3c5944fba4ddaa85"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/photo/slideshow.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a79f6c26eed2cd5f90709398e135260ee5b4b2b68e2803b82f0701bbd7971d96"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/DuplicatesFinder.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f198fb64d5fe04b4715448ed4899ed6885f74e82e91bbdfa36e836e52ab4efd0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/RegisterPage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"756be7d33d48d95c6f8f4da1dee0586d7b4a5e4ce57e5ca53e26417e3c77ec9a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/RegisterPage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"467818b51b66ad8cd3de9860e0335b559121a3f8df294cf79941a3a464cb91a5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/FixTreeLine.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c7fc8c11dea02ab9c05db4f33d7bf5e86c903a7119aab3c8311b8b2932aa982"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/sharing/BulkSharingModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eedfd8faff09fd72480f424a7648b94ed17aa755d9b188ed7c22a6c28646b786"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/landing/LandingPortfolio.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e16c4b5ba3a124ed96958fef44b39285a9050d23c6c6ce5b224976b25ce604c0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/shop/PrintPixelSizesAdmin.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"24fbdd8ebd874b6ce043d26465d821bb60f61797f041c0fd502283b2991b4c2c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/people/QuickNamingInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b76d73fd4c38ebcc485bd1dfd54f8ba8a4eb1e9902b8d0258897d974f1297c8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Webhooks.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a96f67b15185a9fbab33f32355c63aa066b2ebf6922cb98005038e8fdfe546c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/profile/SetLogin.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7cc7e8232362ddca10b8a0cab983f3792b126b151b7fdfafd52f37074d1b8d3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/ColorField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"571dbf40ac1adc39a3148c95f452d382679f469839ed16341e9746f051dd0b23"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/config/axios-config.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1764fa1b6809cae54b323e1b14431e6ccc2696b60391518ea30665c8aa2c7131"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5125d3baf7727c3fb0edfe193b847f93ae00e6a3c1c564ec629352c10036d6f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/tagModule/TagPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6855c35a1f8dc4c918ddbd8f72d15c54528da8f3215c8d47c4bf08696e8004f1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/auth/LoginForm.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"097c873111e87f8c96b1f7328138a90da2fac341f4aa7b9adf7149028df8491a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/AlbumHeader.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d76107f87ee524be3477f2d64c6e74ca7e3725367a2e58f173daa588fa6e45f8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/shop/PrintPixelSizesAdmin.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf029ce5233418756107ba020ffa53978241b391fdc0f8b39d30b58b2692becb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/landing/LandingMeridian.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c0589f96d62d609a153f3ffa1351204ae3164485a2c4be1e843a176d8e576e5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumThumbPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"edee4f9cf383cdd4d8fe155418eace92b0cffdcf8216fc67182fedb4b7b0f847"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/KeybindingsHelp.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"60444e091c510990fd36a36608ad1d027677c6a81336aebdde1eb1e8688f30e5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Jobs.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"39f1fdd202298962be9fb418a5b4461171cd2118e5dc33d9838c24f2fca764f5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/AlbumThumb.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f13b9e63cd5d08b604d7dfd49d26154ca6ebd1925b5f012be97d9bc70f7232f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"17a0f4b3d790ab9d2c38cbc389b78b47fa823aa962b95accb2823e2b994ba978"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/card/Card.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e585319779714872fe587ea465f53d2f71da00558e170e334e916f915b98c79d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/card/Card.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"095cdd200f63b419ee383e1c39db9c6efe06bd1ed005141287d4032158e47ddf"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/Webhooks.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c68a6b5dbcd38b5e88bf0edaf34014d156d96f7aea0e22e02c9e33442ee10c7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/maintenance-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"75dfb21d11f851741fc97f31144929c01cb2d0561bfb26047d26da43632764d3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/card/CardForm.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a41c79c105fe7bda722b0ca83fb837fc15089b8bc939415e38acd982d05e775"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/FixTree.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"222046ef67e5e407823a5cc473e68c2bfd2b447edb59eead30fa5f9f3a0478eb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/quickNaming.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2eff06a639916c31e8ae95e2a8030fa10cbba19a9bd4536b3b42d2ee7230b2c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/landing/LandingStudio.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"28056a873afc6ada0417a766a24a07b152f4e5c19f675520a105aa5d39cc2805"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/tagModule/TagPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6474742ff6f7cad70397555b4600658b6c83ee21c52f454b75b30c3c417c3cb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/gallery-dialogs/BuyMeDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbae45c2df4eca2ef68c8ed5fc9639223268cfaa675f8cc8ab8725e8ca3902b8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/Dock.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eae8e046e02168fb00df7aa00d145b65cff84239667031ba8d57cd0b577da1c6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumTracks.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a66f515f716f81a544ee77718c40f94ebce81438ed51ef120fef70aa33177348"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cba319f1bb13b1065ddc4c6c1436010a8bc564d33cb74969f5a3b0589a00ddbd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumListItem.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"20a6d388c9136174fbc05a4fbaf7f1362e5453e1de93ace02916c8f95f3baafd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/card/CardForm.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7a7e7da9ce48289e2cdf7ff9b70caec2ec738c3df9b8f3740ef3c9c0f6ebefd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/statistics/PunchCard.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"67c86d8a1cd1a6b30d87f43b2ef9266424e15b62592587e643d1f63f459c4343"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/layouts/filmstrip.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9660016550d00cef92644d5133ca0c78ddca4c083608982b06b22168889dc139"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/faceRecog/FaceAssignmentModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f163968068ef5f1f3ba7d544520903d52d110de3db62e4b8d24cebd8d152c84"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetLogin.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7be8de00420a821662a78582100de871e2418c1cc3d543f8a74fb5f39cc39da9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/PhotoListItemVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e1f7c9072dc2066c38f765d1745fa29e6b9be77da9844c7ea4d45afdd583f9d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumVisibility.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b26e46c02f3e7f1dd34b4d4a97bff268e56ced75f07a7fe31e2a390075fa5787"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/TagsManagement.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c6adeed45d769255f5354ac4980f16066c80c26ee5cc971dd8234d7390d73e8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/group/AddUserGroupModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2444329806b1f73cd36aa0e0b0b629c23622944f2034c24a5d02aac112d522a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumThumbPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6c6e1ad3ee51c30be30504d3ee2258ac31a174e3c0d47af79eb67acbc057c33"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/FormatsSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5a699c0030afc5f3826d20c404ad690b5b956e66a42b49ed2e44707a1c1dd49"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumListItemVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1960aa254c6e69a6f62af178b98614b7f8cafe612501dc69a04a5c10890cbf27"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/FaceOverlay.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad25c1158efa3c3e122993c34fb2e2ad2c7d002e933c63630c85f90c6379dd7c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/landing/LandingLinkFormDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e16f8aa001c8bfa59ea83c8a35250edbfbcaa965e58ed0959906131bfd343db"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/PhotoListItem.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e48861fd234158b5dd912905b0657157d259e1b567b7492281fee3825dca3bcb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/DownloadAlbum.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"78d53d120e39eb99927fe402bd8a3e0f63585006c8f32fccc082e4db21b3dedb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/DownloadPhoto.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab5eb4aebeda395c328c048cd6bf95413323249170e900f2a7988743fe3b19df"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/faceRecog/FaceAssignmentModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa487f9d1ecb6f7e2e6b0c53dfd3eb00367c3cef408e86c27ac637d13c3dbd7b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/gallery-dialogs/BuyMeDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c59f243ae7eede6cb459bca8904e353add1ef40e07695b14f4851b7747bce40e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/checkout/useStepTwo.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0007626e6a3d0e0999a4342918b97e3ca8412ad24089fab2385df1e2a7d8a962"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/faceRecog/SelfieClaimModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef06e2bdb6266cc19f2d9ac3e9dce310bb17d68b8cec28b945a950656d83d011"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Users.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dab9e2839c595ce3766c50baf769c861fda0ab4f781bfda96847b04a581f3390"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/virtualAlbumRows.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"00006f1f38c1291ffd5ccdfa626a0bffd96da6329282c2fe9d01e6e77301dc3b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/modalsTriggers/galleryModals.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cab55c5668f7aa51c47a98cd95886e16d9aa8cd845f458345e16842cc55e4976"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoListItem.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"860ea8df4ed353d0db69eb0308f0853e2afa1f81a5abfae41839b65b66dc69e0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/Dock.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d7978df2493e2aefbb3320bd38f7fbd86082ddc9e1f9d63219c427c89caae73"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/treeOperations.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5093232b1f2f8bbb588984e370a6ad7c2a9d3a8c6f5d460c01e7d5632461953f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumb.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"607d8cdabb18f46a00bd95745b124679108a76345cd04a6f7bf6fe7c3564c64d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/statistics/Activity.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9cb44dda769998db9423cd3f106943706bfe617cea4d77a6e545eda810d0d31c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/TagsManagement.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bcc1d24d6bf6e9e2d233b9b4c444c6abf7a0daa17e91c2230673b7671d278f5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/gallery-dialogs/DeleteDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"872ae220f67460f9af921ec26842a2aa85149cde454ec8f54f24a6a6067efc17"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/ZoomMinimap.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8838061385b6eff19fa4895995b071c50c234aec897c4d7dbed5531b80a1ebab"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/pagination/PaginationInfiniteScroll.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4e9665e922d6ff95e8acfd81665b76b3042427b2bd09ffcac8db4f58f4e825f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/webshop-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"01441e170dddcda2c62e364e464f1ea832ccd4efdab99bb501b06e09f17860a0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"31d6c11f5494bc871f2ab3b10f2327b850cedfdbbbe98d406e5f075abdec68f6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/photo.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c13db10ffdec7d1aa2709ddf5a42b9808e95c898f0cbc294b3326f1cb35fb1a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/users/ListUser.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"535d39d7a88bbc23fb155a77f5474f6607cba7b39517f22794cd4645cd5a6f4e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/faceRecog/MergePersonModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"adc7d35827888bfc52c47cd01a80ca3b5d907c609d127f0c85e8635e845f4711"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/DownloadPhoto.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"80506e0afd3d99a88e68f0af04788ff0558d0e5dfc4574f4aae4e76965c65409"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/AlbumCard.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"28ff89c00fc7c25085010003cc75ba051ad41be7e38e13ad9f7491daeec6875e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/landing/LandingClassic.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"01b74311d8ccbdcb8d3cc5ba8bcf3de87d1474f86861da87ce5d154c685afacf"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/group/AddUserGroupModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c0b5cdb05408a03761949cbc9dd45faeb0be1fa75cf039803470dbe90380b3d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/insights/options/calendar.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fcf58632a85685ef8945a17e0f8660b34671607d3d219736bd5c509b0ddf9ff4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/faceRecog/SelfieClaimModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5180a8d019d313e5f0baf2b08735b8a615684e11495b178a23cbcf5129a9b7b9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/checkout/usePaypal.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f59ae47116e841f7575609940e3c957d0ef887c07975adbf171dcb8cc24fa88"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/AlbumCard.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce5180794cc0801e87024fe72a5a84ef546f4c31c0f3d76b210ea68b0f699ccb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumCreateShareDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1979a600a2a5d0d662071101d0d352673aa2db3f653d6ec32c7b42f1e7e29f5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/router/routes.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d29a143386a7135f1bdeba9c23d3804cd7a8b469c3fc3bff65f53f0748b1e12f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/pagination/usePagination.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"47489f46c4736390ed3d277cbc7bdf98b7be85e9acc7c20e08a5d93dea4031a6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/thumb-asset-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e4b9e4a2539fe62a9f7c015fab5e74547cdff304eb909c3cf417545a489d61f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/AlbumEdit.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"88bdddf283166353e00bd3bd13cd85cd7fec62d111579143121e82e56a00e5ea"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/faceRecog/MergePersonModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"48da366b4a32ca17d63fe44350f7ea0016dc4903342bd3d3ccf782311cc176e0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumShare.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"35254d222b5a2f5696eb4b90fa24a5e260161067b757d82dcd4dd9ec9f5a26d9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/PhotoHeader.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"db9fa7a3399c6a08087ab9b11c3241b0cfbe572f0dd39f2d3d1ffffe1c890e7f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/SearchTargetAlbum.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"83eafb4b243f760f04b5aa0cfa4afe76193e6de8bc12194d8b2c0d0cfcb03ac4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/gallery-dialogs/AlbumMergeDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ea3a03b5e5407774663f30a9acbd9045bfe364231edf6d15711e0fc8e823a3f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumMapHeader.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb2a5c274c9129ea6885437be724eb6d6a56ab1aaef384dbbe290073d45c9bb8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/FaceOverlay.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5fed6f2a4fb3f62cb58a1b350c9e256a1f568f8db3dcd980b762f82e6718650"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetSharedAlbumsVisibility.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2185e4495a2968ddb046d108ab8db75ec9dea9e5bd63d41734312ce2a886c8e0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/AllSettings.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"190d5df8e7dbeec3a01c5a4164e17c6372891bef2633530e41844a6348d938c4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/uploadThumbnail.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea87c861b3b1268c0234eca7ca833f499585003f8927fa86211162da177f44d8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/webshop/BasketList.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cea993b245858804a0eea01885d6d8675becff1b9a3ddd40ed3e92a83b14173d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumCreateShareDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"72d4e8a4fec13598081216fbd0f80e48971da7c755595668c0fdfb719a949580"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumTagFilter.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a081a03bb95d5c8a6c97563de85d7ba0c8ca894313c2b959c8a2c3c726817356"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/admin/moderation/ModerationHistoryTable.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"047862b73a17557e37063f9e8fc5a55d66040a36fe49505532e99ae2fbe0e739"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/photo/PhotoCopyDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a30f01a541ef835864a323de7eb735dc7652e929bb7662560f8f7a2b4029324"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/insights/options/space.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"971254d9af7b4e5563d4888449aa001cae29facc8ec91f60ecd3d1e6e2307085"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/PhotoThumbPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"84a2ecf52fe08ca40a85953c19113fd94588f0d9345c8134d8f867de6fe57829"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumListItem.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4c3b97761e6f34c1f54a5bad33763babacc65e2bf51bad4a933f4faad345550"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Landing.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c45d5d7cd5e5b59df4d0aa9ba4ec19d61d9d6f2eddd0276274f6a08fde3bbf92"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/Unlock.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8711ab1524ebecc367676d6399e1c10398365f54f7a6aff0854525ec7c9d0b7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/landing/LandingBackgroundField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f28bef889a080893eb7d5d1a94b8e1b2d5474aef4cb931ef853f022905925334"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/frameOverlay.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e95df88500cb7727bc6b858fc72d5218c2be2ddc4c9c0cdd83b3565da2173cd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumTagFilter.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d17e7ebe6fe1e17741cd43601e4ae8a6dcccbcd4c6b1efd212005b4e4104fbf"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/photo-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"031188b4108fb2da691456cf74e48e88340b256b35dedc8aa0424854bcbf35f9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/OrderManagement.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbda2fda41e1280e7b097e5efbe5610d844be97b27d8ddf5035260e5f81733fb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/gallery-dialogs/DeleteDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"80fe1f7d8a4ee042111a47501438cf31d41e30c72897cf2fd5c87f8536567f42"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/Unlock.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6278ce262ab89295695b181a4f3265d18e0b7d9e4e69ed2a53c8cc4efd690009"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/InfoSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1826f6de1c07d4ac6ed82bb73f4f068bef118dd7463311a7d86ec749412544af"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/BasketList.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f6e051e2b6e6683895138d49576790246cc972576b0fbac2b3b0c9fef3bfd7c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/photoActions.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"39d99f334bd7cb8dbb37b8aa872829f261215dc5e922aa9554178ad7f839d5ef"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4acdbb837e52b133144993652262bdd26d508d51de00faea8f1ce18fb325d3e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/PhotoThumbPanelControl.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc2a876a885bf8ab813c01762eb4717a28be205b5992475bb5f1f6e00addc41c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/ConfirmSave.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d654de7525fdeb34806914dfe23271458d1b116cb4fefe515d6f628f64bb3842"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/checkout/useOrder.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"debedf466bdf9a42b54b20ea53308e623fa415d4e5bd8bfe16a7faa8199032db"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/photo/PhotoTagDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f46c8d4520dabf8ab87ec848f7e430643e04f299d28c75f15b374a294d7e6314"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/gallery-dialogs/RenameDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0f842783ad741da6c67aef5a57857eaee65051e216414791f7f0f315f944833"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/profile/SetSharedAlbumsVisibility.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"97a7851575e55e55e11cfb34129509df1286526695227f4865a80226243e7932"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumShare.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c48740d605cd582601021b3b8497b001bd346e9e7a82b7dcbecfd8047fb87edc"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/gallery-dialogs/AlbumMergeDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0a4debcc7aa81bb92c03fc543217822c8b25130b4e25bf28c1599cf18a1ea3e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/SearchBox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"da4e8545f4d172782ede7763bb5a2b4ee9cd71db7b9199d4f0264d669e5d4207"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/AlbumThumbImage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a512aa55ab01e30613af181bca3b37b53165aede1fce4ab932b803bdaa024c4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/photo/PhotoCopyDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c91dfd0292b6d38ab5a2a01ed3a2c8a8976994b1d11b223bc229e286313243d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PrintSizeFormDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"60f9a7f710266eb5d68e29a06b4777fc00b6f1be8cc4113102862d9c4890b2d4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/ConfirmSave.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"866929729d4464544600384aa3910e3ad02f78ddc66c1a9879c21b6925e53df9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/router/routes.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5567e013e5f1cfcc2ac361515eed7a2439215e2329838861d6068017d35195b3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/InfoSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ea1da8e388bfa33cb34f209f14c798d0931fee060c117c99c440acd8c5c3706"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/search-v3-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"42ca102bd89edd18aec524d24d4dcc17c19ce9667b808cfccffb6e698c58a0fe"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/tags/tagsActions.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fac4afb6f8f6b3723079df542ae03d51233edeea9b37227c1434866c72b94b4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/shop-management-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"188480fac7221200f101334563ea02e520f5906437aa5c9463f070c678e8ea82"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/gallery-dialogs/RenameDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9d075977e2d15b9ae43a4988e0159721ddab9f524407ca2ef4724741c764534"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/SearchBox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f3097a50d721ba0aff2eac592cfed35b12e74dcaf1adb14da1bc895efb343ea"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/PhotoThumbPanelList.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c4ef22e95594b4ef217ada06ec26203e8f10f1243b95c6f3cb28d1eafcc2e0b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/albumStatistics.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ecafa92eef8028e32fd306fc25c83ec3155f0f1e23191e3731c8a71327bd4798"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/HeaderFocusPicker.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1817d7f7c8c4a4f9e78af6318431a438f100787f49e9f997a0a7999b5e30b546"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/HeaderFocusPicker.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"69adc5f82b6427d9f3fb7a99c65c1269a3720640b795f995ec5b4b2ca7a49a91"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/FocalSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfb1004366c895c476583917ba67faf2fd44f8aafa1b906f38987e4f0fb6e326"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/searchModule/ResultPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eac5ac6cc7a834f7a7e31589f0d6353c255690604924a7aaf7097e227730a0c8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Frame.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe1e01b976b17f9bbde6a94cb0617ff0f0090f35db6e2f37391361c6c615ac4e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumNavTree.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7cb2078d3b5b95f0871b4e702ab6f3cb161ee5f7aae26c9e593808f23eda9623"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Favourites.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbe4acbac260c511da2ffd2b2231a83acf872e1bab6336ce9a6645f97761a97e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/OrderLegend.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f00afbda9defef54feb135e261e1e5d853b794499ed89c01cf328477824b5f5e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/uploadEvents.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"494bb7032f13ed27e580e05205598f61953914a20912fc768a41ff224dc43ba3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/bulk-album-edit-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"220bf6bf91506adb0bfa781de9275b914bda09179b9ee563e0c35649895ce98a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoThumbPanelList.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"99768575992c78b7f9d2be5acab8f6c640a83a170686e3f171999a70b0f24086"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/AdminSetupPage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"af079cd32644426ddba75fe41359022119d8bd62259858052d8b62a8c86f9ca8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Favourites.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b99a433f82ab8d452c9e7cd9d82f5f510d5435a83b9fa883230d89e6a942a67"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/shop-management/PricesInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"11ec687ffacd133b66e6b4d5fede35569e628bce0a0a6aee14f3426fc1a607ec"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/checkout/useMollie.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6de9ecfffca2ff222c66c2876e68fe4684be18c54413fd2a81e4e0252ca2de93"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/DuplicateLine.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fec4926c230f65ce29671c3806609388b81f8d61b6d5e84501f2ee5e0f82a0c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderLegend.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f7bfb00913201ce3515c33dcc9da2b2cebbbe605cd3accbd3bf3367ab3a45a5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/photo/PhotoTagDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"baea9899c28f3292d65f5832a24d2ce4338ddaccb861df91a1df8ad8099977a0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/AllSettings.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b5c2d6b7d72264bfa63e46004b4dc6ffcfe9c895d26e90a77385a5974a63308"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumCreateDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c67e7c63120bb00343ab98cd1ac6377af8d54b4a008e524ed857b4a9776b25c9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useDarkMode.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"10ee1a04ec756da132100b737f4d25f0eb12d6ba09c0c63b10250b7811c5bfa2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Error.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad7ee2b734912ef05bcea624d2cdef61aacc6df3562975384bd868ffe016653e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenuAlbumAdd.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e009d9754faf1b48d88c39caa8e8fd0ee4acbe09a08461647ddc9f8d456b981a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumCreateDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7025b724f9173d548428f065867692f065f16d525b36fcd2d52ff0326b435aa"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/footers/SocialMediaLinks.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"222323ff7e4f8ffdeccf070a4d49079c11fd1dd69ba2aca47e1543d5c0a406b1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/main.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f81c46039d2f0f94be62198b9907e980c7eebc8b58825f41371850b95e9d713c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PixelSizeFormDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c844193885e00e51d4e257b3baf666c46469ae2b82ca64d3366398183111a3d3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Error.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c56dbfd37db97f71bf736da6f2ad4be7753740fb869bce03265a90600d604180"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/shop-management/PrintSizeFormDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"734ca451e172f98f2fc0bea79d74b84b9aecf9526df24556e9b6277f70cda099"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/albumDateScrubberState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fc3942450e8e7682a16b72f33338ce42ff0f25d0f43f4dc573cd07db2836d51"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/ApiToken.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e36cdfa74ac03f0b4ac470937c34fdbb8aa547b0811b6663d3f7c670b6f8e12e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/SecurityAdvisoriesModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6821f3fa7c3f1c05b18ab235d5655b4622263ce5582020749b2df4634fc02626"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Frame.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e7a7dbf15799f67ce7bce2287276c501badc18313c328a9d5d9f8f5999d685e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/photo/PhotoLicenseDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"59bf9bf061dcd6ec8279d86e00da844e26d922b0eb5459a4477eaa4df42c0a50"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/ExposureSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b667683c25d77af27a7b2507c73d72076d979497d4bd15c1faf3cedac03a646"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PricesInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"08f85c444f59a874ddbbfe9480f1d03e73eb00395d3c3d470d386bf466bdc130"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/timelineModule/TimelineDates.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0ac013e51432f8c8075c7cfa1c378e8b5f213446c110d66843b12093f950da4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/timelineModule/TimelineDates.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0dcbce73fe93dc6e67d5c186afd1fa7adcf4d9b21a57ed1e80f1e9bbcb3cf538"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/DuplicateLine.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa25e4cbd9d1894832057bdbfb6e3d5f1f65282d924d02830dffb84f2cd478f4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/albumNavTree.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"50e3fcaa326fdbc1a1279ef3c49577a9cef0dec950b2de569ede0407a8d5cbaa"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoRatingWidget.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b27ee1736413132f58b98108d0331ed9646a372d7879bbb63ca969cd1fd5c99"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceGenSizevariants.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c483e1848d87d1d03af2e9b5bde2bc9f23bd0135d21a5e41db6df73fe446e3d8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoRatingWidget.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf352b5cb531145cad39854d86ba4f2772002961d8def3265b885475c2f81f94"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/WebauthnModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"596531247f8cfa238c280251a2d0aa141482cc5433eb244dbe1e730711fef81e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/sharing/CreateSharing.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"938546df9524d2f2bce992ff73322aa537ac5fd6abd0f7d544a4940003fa519b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/RegisterLychee.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8343e50e7f32661acd216259147e4dfc923c126d04b0f479266b1fd1f92405c6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/spotlight/useSpotlightRemoteSearch.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a623e7dc6f28ca94edb8c03faecb091ff2fd79fe138da72e529659bc6bcbe72"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/LoginPage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9929529c232c1dcd9a0dbde2b771e2eb46ddf0cfcd634a1585f005153b5e941a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/TagsInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4340f912fb37c6ce5c142c4a6d927419646f0cbb0c5ed32a0d16765fd0c001b7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderList.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"25c793d50ba4cc05a2a7029fdfc2dba96ae7f63369306751fd9d1d6655a008df"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/sidebar-map.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1eaf1be077fcad1dde679037ffaf255641db7ed38d9d75ee40ad849dcbdbf508"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/photo/PhotoLicenseDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9aa15b760247e4fd3ba8049ec074f6423b7b972beeb8252114ca85929ff6044"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/TagsInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f372d39cf2faa3ac24787d96c933769ac3e87c8827d741240c8e1597db9fb3f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoRatingOverlay.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"69f548ce51c472bd3c3a3bf1cda694514652feac0bf8dad9ba52e39f038264b0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/scrollable.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"447d13d44772a7222004e40f45ec37f14f7e1373c6ff7a07affb60abec6327c3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/SearchTargetUser.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a2638bbdde0380946eccdfdb3212f6f811302f9b6c0fc14bea8cf341d0343a2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/WebauthnModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"47a181dabcee0db062eccc63d0e5e4fbc7322c0db6b3e4e61f67cc6f30881ca2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/footers/LandingFooter.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e151ab7109056612b4b3dcd243cd2f11d66b9af8a833d8b5bedfa67513aca2b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/bulk-album-edit/BulkSetOwnerDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"249ee6f8caaa678e5ba271747c9d766321d7439646636f7f56dba20fb996ff85"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/sharing/ShareLine.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a7d30ffd05b139bfc77127b298cac1540f8321177496e96d75aa0af9535364b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/shop-management/PixelSizePricesInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"651480aec3d67f7780bdf8d2855398e3d9979eb5350b66646cf43c25c290a543"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/TimeSpanSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3c27c851d85f0674daee70a9f420e8a72bad7efb473f2b79ecc7e9448ad74d4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/faceRecog/BatchFaceAssignmentModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2eacfe8a62022b1e7a8635c3840306474504e8367623085d468f9b4af82e7261"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/statistics/SizeVariantMeter.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"35ce2d98314142f979ba724d36e785994a23a6193f14875a8f461dc6e66c5ee2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/sharing/ShareLine.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9fe55c8f6c586f0da2dcbf3e359dbb4ef7e974370190cf01b9b72da514adff9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/faceRecog/BatchFaceAssignmentModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebaad9b5b76a50a3213240b43025d296f730bdd02b22cfa4983d40359c9d5765"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/landing/LandingPortfolioFeatured.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b383a9853582d157ee2fc5e19b7e64b9311f5b99dfd121e95402c6c3426b7390"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/checkout/useStepOne.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"91ef8adde9eed27a8e5d9a419429ee7a74782a8f45f53bf08ef368d81c0ec9f2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/NsfwDetectionOverlay.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a3da2b6057bc5b275d9bd5ba22738624ceddd2826010bd8fc367f782812fa14"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/NsfwDetectionOverlay.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"34e17777f218a5c3516047265c26d0e65d7882bf46c59778f4a63e403d7bcef6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/renamer-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8265243778e26dbef8e6e63e4af9754b9f5582bf565d4fe902a0aa702708fc79"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/bulk-album-edit/BulkSetOwnerDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c42d30b31c26c564725b29a855cfd8dae0f6a921188d1b2556ea841e940933c3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/AboutLychee.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"13d39c27daaf119b1b39dcbd7f1c0562d8f0f3bde383d376b5e7e2c1e422079e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenuAlbumsAdd.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9840b9df9e924662454d3676004029342690f80bf135ca954bf06b3e23a34991"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Purchasables.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c874a9259380729478e54b257ae2be2b59c2eb46b77aa1f5562e964947aaf603"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/PurchasablesList.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b3409ef5b6f85065d2ec2cf00d8e65fee20a82431f6f0993ba7d52c3d4768906"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/SearchTargetUser.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eaf84732dc8616e6ee85e035e0b462d78ada11ddbfea317886082a32de4a3c64"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/shop-management/PrintSizePricesInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6846194825ce574fdd4251db4c10aaf282319f9dafc6d31051c6919745ebce3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/contextMenuAlbumsAdd.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2019b875b402ac73106e47c62f908c2bccaa56b1e2d4f60fa36d323fd65cb60"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/usePanelShortcuts.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1018183fe40d2125ec3f8100b5fcfaada86fa0905144ea78ae0301e0c16ce568"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/layouts/PhotoLayout.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"346ed7b19686e5751092c650dfc6a1cc1f11ad609bf83baceaf6e190c0f3fa44"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/insights/format.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"608c02ff4d808b1c5db73e5ab2130cd914673ce235b7bf59541b6c435ac97c75"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/app.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"98c69d142bc0da700cab00b7303e4cad02c1b4082f0ded07e7e02d52ccc9bca3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/GalleryFooter.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"448735917b874401d08877cd74fd91f21a61e12658db146adcb197085afaadb8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/shop-management/PixelSizeFormDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae9fb380a3b8f67dbc836b3ec789c252ef827cdb1cf086eb74c1a2b626db999c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/PhotoModerationHistory.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c5b682214739bf2faad06a13b22a4d28775b858d25eb775e10fab3a581d21d3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/tags/tagsActions.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffcda9e1d5a8cf46e023133b956bf1d5509f7d7c9fa39bf83f80c39839e62fce"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/PasswordField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"babd902d42fb68e44f18c2b190d8f8fcd1c6598a5f29958cfb9335915c077a72"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumbImage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ba6b261ad12f9061ee9333628aab65a0520fdde9cbdc911650a3a650d9e5715"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceDestroyDismissedFaces.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2176532ee44fb658c219f6eae45d0eb1f3ca6440f146efd898b8d5d6292523be"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceResetFaceScanStatus.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2f02432d01c241afcfedd2847fa31b149901f388ab084021bb0546d9be339c8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/search/SearchInputBar.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b52da64ec1bf502bdd712ce9dbda9f7f9ef52bb79f880326f5a28c1350ed11e2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/PhotoThumbPanelVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d319ed29715711b58afd7863c1cb8073baa0e9e185b55e350acc6cf177261a8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/RegisterLychee.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2b0e2ffa8177ffbe9dc50880ce94ee8e1cf1e5ecb0de515dc8b66274d28c091"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/albumDateScrubber.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"86bd3f10de8c2f5ae6d8c681dc7060a714860316167729ea629b9e809ad7217b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/PhotoLayout.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd7767cc76d2b42a2fce752bb8d6b32a2802453fb9fc366083f4444ec9108275"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PixelSizePricesInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5777fabf9218d8804e1479bbae317a64477bc7f1e60bf3dd0879f138124f27f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/PhotoRatingOverlay.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e53751bfb956bd9a98120d84861c5f86a8b4a26d7d902030d3dc1eef5be7a4c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/statistics/SizeVariantMeter.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"29dd44fe177d67d3becff46baa9eecbf03bc60f5ca84127608aa63f90f191daa"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Sharing.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"97556230dcf508515c92072c06c2352483dab36b1c3fab307a7f93ca6b3f4c89"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/PersonInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c94f218a4c20630425a70cdb9c4e5ca7b203b1ea09538e46e09232a1984b71ef"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/upload/DropBoxChooser.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e09540001bc958be2dd916c05ea11d1e8e81a0e3fb24b2881d729df3dcf5d45"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/statistics/AlbumsTable.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bf964438a5e8c6d8d1bd1aec106608dcc059094b9d04e81f16f1d9261f5fb09"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/photo/useRating.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"45006e430c2f83c18ff80f42d634072b3402ca56c97d9cad3e6dec4c019393cf"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/AlbumStatistics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"00dd9f26830b905bf19811a7531020bf55cb2f67b0592ecaf57e0a039952eef3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumCreatePersonDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5cb0e82c157c29501b089b0e7d32ff2af84898a60184bddcb8de5dbc628678d7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumCreateTagDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"650a4665967594b52f575b4909934cecf141bb99527efe3a68faf5452c8a3a63"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SelectOptionsField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad6155f8fd68c09fcd126c926b284018e11cc6a022d4825a32ee3adc353d3155"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/upload/DropBoxChooser.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0c15d965b62ac1232cce47199302a15bf377e25c7dd2f4ed934de273432bf7c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Diagnostics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ffde5755cdf519d4af425ed7aa252fe95c8da1221d09a52e27f5880b1de6419"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/AlbumThumbOverlay.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d3122e4bcaa0825456170c1a18c4fa3b1c3121736e15daf1f71dd74bddbc8ef"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/contextMenus/contextMenuAlbumAdd.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d62504708d1fdafe6ba0315d6b801aaf0ca89893b4154756c04e572c977004a0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/PaymentForm.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1178843140a5f16169e64304347d7a1621a37e7c48b967b4379fd8b610d5d608"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/LoginPage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6cc0fcd14797861f2c604b5de650528824e49e03433daffa1b5c7e516b7e8f1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Maintenance.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"adc497838dd8386591de483856b807e33223e4cb06177e7c27c14b103ac9c7fd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/tags/TagDeleteDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"949348b31bfab3515d4f6acd13db9f95a4c261d30b28140edf1e90d2e04c7115"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/utils/Helpers.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e875f0af2e99405c72c6340c18dfe0883d1bee2483d038723d4f62b6ce73ac80"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/PrintSizePricesInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b10ad8952ec180532b727005eac84eceb766a7502e627042bc8c946f341acac0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenancePurgeOrphanFaceEmbeddings.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e30338edad87cfc7427818913c237b7494118a3119b0afe85fc36ee18594c3b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/ShareAlbum.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"706b8de09af8d3a816baa40fcccaaaeac50d3c620ec5edc92234ba596049da10"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumCreatePersonDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"82d02a8404f3211bcc2cf8acf1262e8c3ee4fbdfbb3b75448a8913b990942f3d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumCreateTagDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d6651b8d2e6bd834a1732329a351e1ea65461344d6df82b713bb3f3733d2434"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/contact/ContactMessageDeleteDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f12f672f58c51a16ae621e8bfee63faa791fafa9000041a4907e91b16e0ed929"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/SelectOptionsField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfa00ef64821692e5dc488081f764dd74d84e9367f17e878d8a8f43cfc2bd13a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceGenSizevariants.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f3363f3f0672198030aea2942516d0c9d57d0b8aef1c66200799dfb276a1ceb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/AboutLychee.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d53d13476f5727ec76659d69d3b33a6e300e156e5877b8d61906a55ecde2fcd8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/PaymentForm.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a84d635262c6cd7c4c6c575574630e0d599d4d3ee458f39a0fd374d5c05f9416"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/insights/options/common.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"598cea66e36f9057067137f5530438ece20f4063516b26640c0cc3d66ff99d5c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/map-v3-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc54dc5f92bb0b5606149db2003753e19f72e3f8db81f7f0f08e9f10dfbb5a29"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceBulkScanFaces.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6c6c5fe777300c7158a002bed069a091e8f8a6c33847da4223fb85eca670543"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceSyncFaceEmbeddings.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f536cdefb488f2b22d8f2972d2df76e09043e300708846d1cfda05b026c5774b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumThumbPanelVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b4d89f1679a629d8d279ed8635374b8a637db345e899f264d95d8179bf1cc63"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumbOverlay.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3508daffdd7ba4fef144a2c84e9d42f2ad300d939f2e6d381839b9b638cebaa1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/AlbumStatistics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"82de92dae335c094844823419fe6ef4baffbbce60f44f8f4d58e8709ff212733"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/ConfirmSharingDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"75f68bd4aae8275d4b788ec08ad60509d3d97db7c0da8d82a28eeaa45f6fc440"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/webhooks/WebhookDeleteDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5fc7d6b7443b06aa3aad51cf61c5c791ce21df14fc082f822dcf3eb4445f6ca"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/landing/LandingMeridianRail.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf7454fbb2c80a2a6791f77ed13c81487bee66a9adbef64c0155aaf2b4cf8254"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/SecurityAdvisoriesModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"afce9819611dfbf1c6dc2943ec648b5781ae90213021a08511ac4c0fd7310b75"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/ShareAlbum.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ee2b25344c4a4cb4fa8521afb5e93f352e99eb0710b01ebc347ff4501ae6641"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/webshop/OrderList.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec40054e9ea77d9a26323266882b48906306ad7a7da4c2202671f9c21ce39ae8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/insights/useInsightsTheme.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca57c3cb93a4c391607a9f768f30dd08a71e96f6b08c4ce11ac6cb39c94a7f6b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/PersonInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ccd87a83a43da91a7efc828eb9a1bd74ddbb761accabaa1ce1344c24258f2691"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceCleaning.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"051f4610eda659148f07286514c22f972d21a58dbeb3915a2ae3090bc8bd3828"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/useMasonry.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"74507435f43880afdd795f9582e09394c01df17aaf902570211573e8adb990f4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/ConfirmSharingDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"164330ba2062df2d04e417d4345135cce3f3205bd00af7b27804f46addd131d7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceBackfillAlbumSizes.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"90e45449c2a3182321a7463151c1ddcc6b49916a7c3ae2608a2231a7493c165e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFulfillPrecompute.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"33b2ad680ae646005d091c488c0619031f9ad41c561d5445aba219a0260b5ae0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/statistics/AlbumsTable.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"75408a22f1166ad1e63e48028e98be27031c0551f8af1b57e512f786db8a9b21"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumMove.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6309188abc0d366a0739ee02e68d812f86062987d441d87ae33d5ab915403b6c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/UsersAndGroupsState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"53b5bcdeeec6482bd2714a0f24ee3d7d4a279ec1f2b2dbd4f3ac58b642427937"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/InputPassword.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5f6f4012762283aabf3e9b06e1504c3bfa4edd1a3744810276c801d087fd5cd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/profile/ApiToken.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e486964ec0efa8e31a9feee453a94b10a0c2a1cf9080fa4a2c2b5bceed4968c4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/PasswordField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"176e08824a4005939ee067df65aa63a1b49ea7c48627dd848bd0cc2de98ad690"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/icons.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd4dff37cfaa707ed97a56c66427a18e4fc9047db2305022b0cb4292bf27aa2f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/checkout/useDummy.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ac35bf48c357c704a839625bbba1048fcba04f497ebdce48ea431575e7db94f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/user-group-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eeffcc2cb241a472d46012a91b1883acd88c9aa0fcb87756e9f7524215318b06"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetOauth.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3a070a47aea57657d007e3bf666eb904ef0cfed4c53ea839da2cbdc03d12e4f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Statistics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4423965a8b9114d9a84fd325af1856704f0f07916bf6fc0175393ef7234c4c88"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumDelete.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"12cbb6d9ce38aa95ed0f790fd351ad48cada01f8879776f23b24f6e97ce2c7a4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/SliderField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"234055c5bcb5a010e5a70eddff595ecc2aa09d0b553d849151ff356877f75bd4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/Maintenance.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eef0fa7ca991da417e448abe4c8d0a53d8c432fe68d60363ccdc8a95c1050dae"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFlushQueue.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff30d44f5c949b24ba2f975b6fb57a93469f9c700880784cc4cd30665cc6cf63"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFulfillOrders.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb5679216acda2cd5b24f0bc7c2acd7de1152fdf03cf3d92cb2f6b3150c6b0df"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/ImportFromLink.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"076e34a8aa19777b5b34a8b37a1c249a543899245b89a621d78825312e42ce2a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/diagnostics/ErrorsDiagnostics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe3b56bb45ca47f7b59f324dc2a9912ada1aed28ecf1deac423f86e17c8622f8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenancePurgeOrphanFaceEmbeddings.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac0d996221fd1f8744a510a5e51cc74fc63776841b11f429766ec5c77223b879"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Diagnostics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"940e22791abe0cac103338f4c3511eb2b0bf23123dcc14bd18f0fadbb88e409b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/webhooks/WebhookDeleteDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"347a3c864cadde0db40bc4cfb77b7460e8640c95bb9c274e8cdadeb8a63a6d99"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFilesize.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b09bba6091c0f263b0639aea1b167a32ad086a942930f90009af47e99799215c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceMissingPalettes.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bf22c8465ad51a17c99e456cfaa1c3d2f5ed85e73f6b2b3ebc295186b6c59be"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceOldOrders.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2dee9ea736330b7e48dbe25c27ab49965527789419f378e57286a636b763200c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/StatisticsIntegrity.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d145d575e01352e3c12e2e854cfcdcbb1bf3b76e2d16f3465ca68b6043945bae"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumNavPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cafc8ece4ff38e92551c44a6d7cb9a933ac8d5cc037924fdb19e883bce589248"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/SpaceDiagram.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a98a0afb01626f304c7ec664ac2d6da0cf1a446b5a8c8ab1c3b592645ac7680c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/CssJs.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5eff2780b6232e24bdc7c40fd8c5879f966123dfbac40a422a7efdbdd5d1dd6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/spotlight/useSpotlightSystemActions.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f7c6e087c4c424693d30cf6c8b2b0810fe2a6a6d444e813419cafecdffab5b0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/diagnostics/ErrorsDiagnostics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f7c63c0dedef36ebe05a4a2ed15b23e1eade522c56b39f4fd621f0e01ce4c7e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/LycheeLoadingIcon.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6c7dde966b26f4bd5924e099a36847e645ee1697b523f9aa777fa19f02f4e94"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/Purchasables.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"91a6959976a6565a6e0d2ff87266bc9cbab57c0faf7d4a94e505ae435c9aae61"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/SearchTargetAlbum.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8a1d6cfeb9c2a39d5219d6978eff77a2fd410a7f99def331099e3347287f56d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/StringField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1dbde77012ea4453e1df3c2904b8104ce4b9207151c5572e9bcde1ca4bd6ecd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/CssJs.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec1fcab41a1d19aa75088b7d7bd08415afad5246e2d721f512d0425aedabdcac"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/profile/SetOauth.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9806b7c417631049d67d586b175d22e03ba39c0e899a7d98c7f8a8677cd001b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceDestroyDismissedFaces.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b8f8b37f8afc76cdd35eae8ca041e703615e253e7523f9c84badd5c905cb99f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceResetFaceScanStatus.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef53701e7b0b1f09d4b27ac27c3e5945972c69de838985bbacae7ff68d6d5bcd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/face-batch-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8de8ab5d8161f4037312abaadaef0db3bbe166e5296ef2e4ace7a8027c4c15d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/PhotoNsfwDetectionsState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e79170a92b6b6b6b5619d56df3c812fdd91674b63ce84ec5e951e067f83bb776"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/shop-management/SizeDeleteDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0962f7614b0bedbcb52af2a19d452f5c33fc5d733096f777e503f4d4f38e4ba"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/tags/TagMergeDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"de69de4ba1203d841a611ed3dc81e0e5c6be4bbc19ab976a00faa2eeb39904d2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumDelete.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"43e9dc493dfe257978f0823729abb6030049068bcc50f70502e3de3849534166"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumMove.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea9f23283250fe5c8b37cafcea555f41443c4516a86da50d796a273ee14829c5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/tags/TagDeleteDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cef484f4b43f636afba341bbf89dd463ac6a144b25b92222de4f07bfc58889b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/tags/TagRenameDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fd17b79495976d6ee5fb16bdcbe6c729e217fa43f1482e6ba3b34385bb59a72"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/icons/StarRow.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd957dfe7182eba719a4cd7850a2fae0b243540d09bc231635032fe38308c359"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/DevicesSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e82ec95f951b017926fb87518ab41b9740df2788cf66caaeb7fbe820566e2c10"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/TimelineSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"67ade75b462c74877bae8ca68158a64e8f72fe429a45008b637f47413b25ef8d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/PhotoFacesState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b769a6f50003f19d81dc5d1f4936ec372eed1e0bb2e292b448c626c353a4710b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/ShopManagement.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb9fafdb5d90d2b779bc26ae12ea88dfcb7c95bc5c6f56a955bcaab1172b7c8a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetSecondFactorLine.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e85d4b13ff95af3d13404436bee032f40c8ee42a69048b779b564ee983a0de79"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/AlbumRootPanelVirtual.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"50938a17d6426a80ab14172df705fd0af72629466e7e8662df57238e6033cd17"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/thumbs/Thumb.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"074f19d5013e5b29daef6eea3443ab2948a2929caef60cfd59ba750f500149fd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/config/csrf-getter.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"83f38c5c0c40d9317c55026eab372c06f9a19f793853d74f1b66b9340917062b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/tags/TagRenameDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d860ded94417dea3a227a2fbc867ec3fdd084ae0c09afa949d464c01b2ef71d5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/renamer/RenamerRuleLine.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5841421838bc30aa7fa9941b3e487f2075daca3b681e4ef529aa8257b0bfdf6c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/modals/useAdvisoryModal.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"22239c3313904381ee962128b839a7bbb2d224a93a46bc03a5ebece84bebd868"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/useGrid.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2a14cfed809d8302ae2895aed6dcb0a9b0d1c61657c1443854d2d7f1022fc4d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/CatalogState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4fd33539d6e75e1dde9513ecfb2b4e3d8e41e71cd2d43f842e7370eeeea24e2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/NumberField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"907462530c6c8746d8d2fb8717d84678dfc954e99ec02d4df2a1939f3dde1f56"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFixJobs.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"25f2b9ff1723a244620f5ed006162c2223dbf83f8126f385dec52f8ebedb8bd1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceRunClustering.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c48805e3067aba29d299b40073de924e1963943124919d65870ad6fa9a480e1b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceBulkScanFaces.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac5efb2c222bae6308388c1f86ec15c1320488c6e50ca3a6eecf3ffd46aed47f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceSyncFaceEmbeddings.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"28af22e84c85f5e31dea79d1f0044e33a3badadb610129fb66f1679de9082f17"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/ImportFromLink.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"186a0ee553bd995f923146fa74ccbc8b2ef6aae512aa8e726da9a9950069b4a4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/webshop/PurchasablesList.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3cfbd6819cf0e1b4643c34f7554005d8703c3f6335cfe66202d4d4b3274ce92"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/shop-management/SizeDeleteDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb80098d77191f55b210ec32fb976b8a31a4e7ee2a048bd7900f3560919b1ce9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/footers/GalleryFooter.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7293d12e349942440c13cb0dc5d7ce6c26b3b474d6ea9a5230feb7777aec9bf"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/SphereView.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9993040a4af9735b46243da326f2e9460577f983ca1224167d138c0a4783c247"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/sphereShader.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4f7b0a8a4fd3973999ffc88c11f70d5b579b2cd5b58ee1f9b04759c0e172392"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/faceRecog/FaceRecognitionWarning.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3edc1090868729008282578be8c19645df6235a47879518f0312684f07a9f78"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/LandingFooter.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5eba51e212163d1dfc91f59158e1417632d7f46d061e1ce2a7b0dd90ca338123"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/search/SearchInputBar.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"562cae996cb92c1eb15eba801c24005f8fa04386acb055c285e9a9e8b45d5278"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFixTree.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2b1c666f47295747f2102504b87b94c96f7874e679f0b81966b68f6b0d32185"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/people/RemovePhotoFromPersonDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"da0689f83070126aecea7bf0e42478242ad7ee49d553b673fe6d515aca99306f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/insights/options/rhythm.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9af80edfd713bfc4f5fe88d2d7ba0f73283feea92410baf344a55ecbb0019455"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumTransfer.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"65f04cb74551c4364cfd3184dbb35b73f0a43e9d7475c68a789c5e7cab2d6944"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/BoolField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"02781557a955e0f46ec4f866f72404698ead22071da740737ca0c1bd507f9e1a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/tags/TagMergeDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee0e9ddfc9113b876891f3bf08dc119d035af1a5ed0249aa7eb1739c08fc9553"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/ThankYou.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"72df7f1d98fa608c98d2bebbc72beb88c46f17a9e1219764a9fcba527394d6b8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/OldField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"45bde8958b216a2502f1ecca2f690949db477ab5eb7f5041aa2b9a966ff7a675"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/SelectField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"04389380edcfa50bb2eee5077acd7452869a13d22ce979ef056b8eee68d56d67"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/useSquare.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f1532c589f9d8ca34edaf2aa35a8f8b188f3d6bc3b9dc55058a55ea74098d5d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SliderField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"411ed3b11b34facda71b930383598976a6bba8069dc5ff0e2fc7f096eca0a627"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/pagination/Pagination.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b56a5644a18a084fec859b212774e0c135c3d5d21ab75322d7c0ff0e215faf9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/profile/SetSecondFactorLine.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3ec10c39d2bd7972c8f05ce36b2c16aa16bab9c41ce85620f5e6a48f5861151"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/BoolField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"21af671a475be7d9cd309b4e6bd8e42e6bc0abb5f9d704a21a6da1111b9e530a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceBackfillAlbumSizes.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"441de40bda17545c8463d3795305c7536d6d85acc72634d5a4d35056f4dc5b41"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceCleaning.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"81cb971c55dda6a5350c352ea3abbbf2677e64e61f5573fb8b1bff51e0037597"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceFulfillPrecompute.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6249134c320aa337c018fc50255f5d79505c1f3ecba2fe5d7d91892486d8879a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useAdminWelcomeRotator.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b11bd2c0fb82dfd13ea505dad251c2f6a3fd3351b23c9492c63c93046c0836e3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/layouts/justified.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7eb7c82d2d00a29da6b607056e3203f9c4ef4e80958c03db04f680fe43d9bbbe"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/sharing-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b38d5e55eccc7c9731f5c6f61cfbae87e52ddcf12d456ccc22b3cc33822f096d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/webhook-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dde3237f7c0ba0a8f4e7b3d13107229895b2957285097968a69fd0e2c2149995"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/StringField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"614d12f4256319830a61b4adaf157467d4a2b59686fa92daac28c11eaf255354"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/OrderListAction.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7f5b727d102758a7f904d1fb13e5a1e8be5d65e5fa0a7b91abc64b5caee01d8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/insights/options/squares.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcbe9aee1c0ddef810629551ca548d9cbc5512f27f43ab5a79343eff952685ce"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useGalleryLock.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc3c0259bee30d758c5103e4609a1295d7791a533988acf13c3306ab13abcb61"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/rating.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"de3db3ea8ceffa06141556366b52f0ffa1c22d70f87812c66e2dab45b5a72df6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/NumberField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ca639aa4ba00c2144db29218f789a0ed2e828b86f4e6719ea2f3fe71d06f920"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/SelectLang.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e4ea044f8888b862d45da592ea6d134745611b140ffaa1413af29395434feed"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/ZipSliderField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"005973bfc7bff3de0ddcaa71f7339a24528515e675f4c98d9fb51d1a1b86e470"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/searchModule/SearchAlbumGridV3.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"22ce161057270164dfebfa331f066627c9cdca30b2d26efb601fb70ad0e82c27"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/ThankYou.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1aaaebac3e0cc8ab7b2b6d98e1e387934af3a090c108e8e1e37579c0c05ac180"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/webauthn-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"605fb4d8e4f42df5c238c35ca86fd03683b5010d2db51849953398918c72797d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/PersonsInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"39b1a871a2d041c154a775f0635c73a0e5759ea5a37a954707b4aa04a7da1169"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/admin/AdminTileLink.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"10fdfe19219f42b511d53ab37e886400d8986454ca5c925c5c80f2f02dbb73e5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/people/PersonDeleteDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"42348d149f068b1b9aed8c18b81c8bda3a470867ef9a3ef2765ff31e7bf93bba"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceFilesize.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"26036ae580f1166ea7686497f4ba197684674eaaab9a79877e34a26aeb66d598"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceFlushQueue.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4330f15a82778fab73a69da22441288af3c8a216f02bf4c501028837c37cae80"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceFulfillOrders.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"533dc80def3af1197b637de9f2f95aeaed88a6a38b38e0edd96f92674feca761"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceMissingPalettes.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"180084a112bb69e6f3aca07a157651479723a4adb46988a0930169af06dfdee3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceOldOrders.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4332d50e5dd626988e6e32eaa015892f60030c7386b587bd9d5183a4b41a8b1d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/renamer/RenamerRuleLine.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a84123acc420a24546cbc1fa981f4099ad374dac6a7f5b9b2209c91ee73b006"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useSizeVariantStats.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a51c4fe4b29f8b08f36ba65da16c7c36505306674414d062af5f4a290888460d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/layouts/grid.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"08a8bca77326945a54dacc08bb25851b52f4cf56019dbf89ce04e6a7ac61f76f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/profile/SetSecondFactor.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"37e8fc2d008573100b905611fd87e0880f08b3b5440fefbc458c2486cd5db29c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SelectField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"49a1f6bc581c222a49c1c1530b66c45072051f4993d2430d28e14b50dc836757"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/LinksInclude.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"76257ecb736e5f14d846c418cbd4c51fcb986c861574772a221b636aa9327e2c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceDuplicateChecker.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"12b7093ae105e2d3afc7f32fe23a6e680868f7cf55017dcdabfe36eaca7b2d03"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderListAction.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e421c57ac5e356e98dca090e04acde223a756fe5b143b6df1eb93559ee6d91a6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/faceRecog/FaceRecognitionWarning.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1afafc013865ad68d1e693bc74006e94f74de5db3f9eb81e5707efcbf0aa4fa4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumTransfer.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4f9ec2eeaacc8143af7dcf75c1e82b62b4bbfbdba9b215f5abef6cc63dd96c2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/RhythmSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e943865b03357add037ce98950a6b596b9e591a4bbde18d1eb4560bf3ff9dc5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/StorageSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"39c2425f2643d879651d1c7b2d6e0d2270ee1a2bc2455e1d783f35838ac6e637"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/StatisticsIntegrity.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa756a653991e617ad9d61ec4d474039c68bd7fa1c994b3075abd751ca47c6ce"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/layouts/masonry.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"02d754524d684a90284db55fc13d3b7d61d4b65ca2a9a94217528738995a2462"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/WatermarkConfirmDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2613f069ffd0cfc23d2f414dcb73c808b4267fe4c4142c22f917a65cfe7d216"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/rating.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"55cf20ff21ccbc9d47496e269ff081949835dd549f09c394e238aae9eaa233db"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumPeopleFilter.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa45d12a949e98df810012590f5d08635dc0a3daa4126caf13a08968471444ac"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceBulkScanNsfw.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2626548dce258e1c06c7c52136b403f65928eac47df9f10feba9a940c5af4f32"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/ScrollTop.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"18e4d218e97f6e96aed98c2466b9d6f90d2cb5db17cadb1240a4595e5aa755bc"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/profile/SetSecondFactor.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0989ee88673c6a92fb00a6d8ef1f504bc399a9a00fa7d31cecd9d385059bfd55"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/LinksInclude.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"56cf8fb0653d4c8fdba5a2e1322fc5818242378b4cd17a842e48ea870d14052e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/scrollable.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebff189244d8db797f311a44dd852f720dc2ea27a0083348953b6b42de54cacc"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/InviteUser.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7020d08cc41f865ec3dc26b70531dc2ce81b5b0090aefce941d029282dd3261f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumPeopleFilter.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7c8e48f52e1645b6a26d6497b031a810aff769cc5c48d1b6076ff008d17c3e3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/InviteUser.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f65288f139ac7fe0aeca74e4f2e96fbe485079973ef17bf4c1b5036cfca58ff"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Permissions.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"28f7740e4115c6a154c594ded19a34585bbaecfa9bec5d8313a286279ff1a3d8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/TagState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"de318badb7d345519c21d39fd0504166388fc2bc617f7e21eba07351bc5f4d78"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SelectLang.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"57ac705327a4f8e529f9bd1c0050c6e626c5aa5ab06801dbc0f50b97a9df2420"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/WatermarkConfirmDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ddcfe42545438029ce62b7ef19d5547a85660229136a5ee7f7c0782e96ce907"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/NextPrevious.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"501cffeecb189e68ff2b534a2bffb29abc6dabb39718d8cec97ee32f3f44083d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/landing/LandingBackgroundImages.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"48fc474e09cb16f98db2afc78f719cf670f76443774aa8f4a420b4f10ba3be52"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/photo/photoRoute.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"572791186323e21f69ee0ea1ac5319fc49b45c854af65910c5a944283aa45a13"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/utils/srcset.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9cda267958e5b414e3a1c89bcbb328f8309ce88c349bbc4a8493ee44bef5af3b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/face-quick-naming-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9188fc79dfc27fa951e498fc88386fcb26bce00a072d87e296a1bdfb4e31881"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/landing-link-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb771cb297a3a65806abfe331d6f1920aa70ddf87aaf54ff3010189c0bf43517"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/people-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a32679f9ef1e3eea5bf8d8dfd8129c1d0a5e36f5adf808df9f0ce64702ecf06"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceFixTree.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"68c9c461bcb51a17f4947eab1dbcfb72108ee45660190c12bcbda389edf53969"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/tags/existingTags.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e2d197ebbd375043c326e7c8637896a050d27f73fa87f13d6d8568e836b571d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/FavouriteState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b97d5c73b28ef6fb31755318ce2ea089afe037960799e72557eaaf417ef10ef"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/Textarea.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2aeb7f7e5f0f353123dc4a329aa484d7cb30bc1b5b409530705bf3bf5e4a5cd5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/ZipSliderField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9465638669f1c81fb27d4d7ecf55f9bfcf99b22a7b74e65d4e110f1e17d5828"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceOptimize.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"68697f0fa11fe31cdc5a8c300b4b0f8388a18f7cad7918d32a7a85860505eb50"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/DropBox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"95b5e230a594d7eb012eaac46f5ad79ecd5b91c421fb2249e15672a81a5f81a2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/HeaderImage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc650f84f409b5f52d04eb86102194c29f25f420b62b5e240cfa35ea9be5201b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/landing/LandingIntroScreen.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b90e8e6811f191321caad49853197bdb5a0a86c07356f3a5ae2c6e6a7c0e9304"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/PhotoShareCard.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"545e2b53ea049285572c7f7b8280c09437fce19ed79a919ef102af45aaa1b581"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/pagination/Pagination.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1727adf5101ed329ddd149d9abbe29f24b988692bb56e519ca717910804c105"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/landing/useLandingCtaPosition.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ae5cdf392713658446efe1f0efae1e0ba084004d94c759b7e2d0c5d47c91322"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/people/PersonDeleteDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e478ed82b90ea002186310f8ceec3ccfa9dfeda06d010813e0b8de0f1048f11"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/AlbumThumbDecorations.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6752bc53b5da9b4b95debf2a569b784564dddc468294aa3f1f98e2a61c3e4d51"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/group/DeleteUserGroupDialog.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a2b8fe5578cd3aa17da315c56a06386469dff5b4e5bddf07044cb2c9400d937"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/frame/FrameClockBox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"89d28a7e15bd930a082e6640194aca3da416e26de605a199e3e05659e2a6a609"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/AlbumThumbDecorations.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d22751a5d08507ec3c1411ff434b0f0c06bf8ecfa22e6c464f93917b0d86f264"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/SearchHeader.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a469a05ac6eefc5c30ab53cd1def03b2fae42ee6cd69b2cf66cc8731afb013b1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceFixJobs.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"166d1870883d7a37b6a45009cfb23ddc8eeee8a7b887cc73fede675afd6550c0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/frame/frameSlideshow.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"997ff7d19152c4560af2e3232863446856e52d75005b585be2781c742bbdf96e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/layouts/square.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"60a048a6892eee3731238619a3f18a31e9b6e2e84535bfa5472eda61987f8eb6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceRunClustering.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"590294719e65a8d5caffca95f515bce7a276d42b13460ff5a0f24244e214e925"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Permissions.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fcac6dde3008b4067d09277c11eb0766ea5873b1345530fbee5b53e497a51fd9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/LycheeBreadcrumb.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f757c170995a311ae192a3c1b351cfcf8c7a71abc99a746ff1338c3ef6bd56e3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/utils/StatsSizeVariantToColours.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ddf64d14299a7985b472adbc19a6963e124b2ddd06610ed2f7b3d4706c6fd29d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/Fieldset.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"35b5496cae2321701bae350bbc60c3bb2c2de77a6f0cfab8659eb19225c6ca51"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/search-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c460f3cefd0e117c5722cf6d207e09742e4fdd4b297d642c9e7be126542d6a65"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/icons/StarRow.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"33a14207c09b44be5bd4b2076cff13455eb25d474f06bb1c44d2432aa03024f6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/TopImages.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fa25d92821ec98acd4d5c215bae2dd21a2072e795f5dca04ad62e6d8c784401"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Profile.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e80c8fc682ec0ffb9c57471e7bd6460ea1524a9d209c734ca607e606095d77e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ThumbFavourite.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"de70d03e05963848ef7aa184e7736eef985dddb4fdc3cfb49b320c2b2da44b6d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/TopImages.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"06a3e1eba21f3dd9274ca366bda35d683d1e6e68c45c61ba9ed8a4381fe92b38"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/Overlay.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8be328cdb8f4c51c8573f7446ac2afeb2d5c2d664602918d316ef555263a4eed"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFlushCache.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"86d962891e499fffdba0b8590d257ff87f48d73f58e547f7930d784d36caf93f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/SessionExpiredReload.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"164b5c4e7c1dea180df11c162531886633ef4dd3e57771219f6dcf7693758f87"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/frame/FrameOverlays.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"51007b43fb419d1af95157ccd944052d574343e453a265ee2e61884b43a8a1bf"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useLogout.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9215b0afb90ef3c55b0d65f4eb70e94b88b912f82a1f4535c3e631f8bab19ee"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/PhotoListView.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9655730631e8ce1d443150dc1f2a9e340fd3d7d8b4b249603f4920ee677f2713"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/PhotoListView.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa5bd99c8aaf4a7e66d70fb0178abfdd920205e0067e471831914cea4190b9b8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/Overlay.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0493c8af908862085a8cd43319d2327788c14e065d34ea7f828921e04bac5593"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/DropBox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c266a67874976608e65120df6897fa70060d371cebaddc67e5ffdff0d16c543b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useConfirmDialog.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e38efa63c160ca9ae09650dfdbc57d03c4dfb3a5d22e2288b171c07362fcc39"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useScrollReveal.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"088f529970f1bfda7b798b7cfc7b437dba7b723a1a76e16d87956fd5245e0a17"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/adaptFlowTile.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"11e9b7f1b85b00048920454b506ffa757833464aa1479ec3e9ad962783dce2a3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/app-v8.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"113ae9812927f105425def91362b7c7d8dcde836fd67d313c24e23fb137639bc"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/metrics-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"16f8cdb120a1fde23c0880bf5fda84ac2554b4eaad0491a6d1b5120c92beab88"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/InputText.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"47f9c6cb4b03c66f33bdc2c5e4bf384b671d5489597dd391682fc2378cfde8b5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/HeaderImage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bfe6a1da472ad80460b7e4f80cab4f67eade5d4a7285459cb7c03ff8a6e9126"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/Disclaimer.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1968c3de291d37520c07681cab9b52c48cc950b2ad209b251c4daa152f6a277"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/CalendarSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"befc5a33fd8c7e0a4b2a12a2eefeb58f16367babb97c46849e315147a3cc2ef5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/OverviewSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c429ea6621b11950a4aa283e7e3275a09775a09a96d63599e5c4da3ee3adde2a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/GalleryUnlock.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"73e7a298b47429c02a9ec27cf978ba0104729f5f339531668cdfc3a05006de12"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useGalleryUnlock.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"11d249a601eebf636537707d0a029a83100af7475fdafc77a6e59e375a450353"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/landing-featured-item-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9021dae6473c8034ef749ecbba07adba80df926ac6b2f38ba3b67a12becf615"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/StatTable.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d1a42677a7a403916a57ade0426e4c70eecdaa0e6d7122058895cd658217a3e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/InputCurrency.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4328944fd341eaf61f7640a609f704ec980c725c0c478273759606fab0ccdeef"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ThumbBuyMe.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c40a28b50c651391e03b0f11460deed9b7edf8d7d9a9d1e5ed88640c6e610e7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/PersonsInput.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"66464c22f08b232ed47385521e88d58af6eaa54b3bcffa33ca0891432edb41a0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/LigtBox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"af160a5f11e11b072f33cc86e364b1c78dc93d3948c8a279e9222c2a6b793187"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/Disclaimer.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c2b506f1e3b454eb14de01dd2121ac742346c48098e0eac72251a1e69d5e155"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/useJustify.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"45921386ef25ffb0394fedbdff01a1bd1def32e50c74a66d995a7cec21607d65"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/user-management-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f60f42815a66e12642b0b8d382b158859a8e50a59724c61e8d574905aaa1f3b7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/ChangeLogs.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"47d6df422cd11932f45711b2fd6f1eddc858ce8b8583be3b129c14eeebc4c973"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Profile.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"51975dc4fed216bcf043e8bf4986bd164c5c9445d2dfa588924f43be993d3438"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/insights/options/devices.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d20c2447d2675d90d1c3c494ff6435cba75e690320e96eb15dea0ab814564cb8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/photo/getNextPreviousPhoto.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a08f3f65e33f40f9170b06f32a76c96ec75b73f07f82c0419931de21fb47cf8d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/contact-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"21227f756fe2e03ed9bbffc8f395a6da5d84bfb07023db8f8cc9dc21a00745f3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/import-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e8816bb6e5c4116804f6f0c3a71a7688f3c0d9fed8bf193215d20195f4af7b9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/NextPrevious.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c43abf486b42f92bc89cc37af620d0ef772306c97b654322a82c5f5c0f08a84"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/pagination/PaginationLoadMore.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"954fb07b88bdbe5a1b64945702aef1c690f2a5af2e228e7b8a3bfc02a5772a15"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderSummary.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"81447e3e3faf6807117a8289a4695934466a80f72acb64bac100eab54a318476"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/InputCurrency.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f8df66ef919494ff037e02557a9e7f00991ff9ef2dd29b0ac87da39cd92f34c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceBulkScanNsfw.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f941b1317e8f2815a5a526de1105b75290f2c34a10109b9f05b44a18268b0d5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/albumFlags.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1137b6f7dab81354afae4a8d7a8445a22ab3a7a9bcedbcc617fe6f8b4e0be3f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/profile-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5709ef46c5fd2b0811dd78242faec7e4c81156cd70cd89e67eab11b611be5f0e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7043b4d00725ead5209f0385d33d4b9f9bdb130799bb548e17631142c66b681"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc19d895759b360730cbe8c4c12b8f5bf23a3597132264fa771772db4a0013c4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/landing/useLandingBackgroundOrientation.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ed2b9767a2f9e19926cc5f77ea68d5621090888d009168ca6c232e3743ed599"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/uploadList.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5935ccaf947086b8a7d13ca705be1493baaf327e64b451ab8365064dec2d0362"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/getWidth.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a93eaaa1a0b7df36f9f61e1351bd4a0623a71f76a92f824769694c5040c54d3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/face-maintenance-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbac2928d82e7b08213660401ac00af03a1f045a7e062c74456ae532105de33c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/SelectDrag.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"962a9fe3d1671b775416cc5af01bce787e58431f374f8e2ffa018db53ff7fa21"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceOptimize.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9786062eabb7794ee42bfcdde4d37cdd3820776cfa0e50549870eaf2ff946db0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/ChangeLogs.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d1ca20df7fa1ef605ff142fbd59dcedb2106f2c7902428c6b9181e85fe12530"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/tags-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c78e3d4862633af3c72598383434b9c504f94c7d9f50ef4ba6a6cca943d8d951"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/LycheeBreadcrumb.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c7569f31af65b743cc0b7171a62026a799f4233f477ec2e9a3eb2cf512004ce"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/QrCodeLink.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"53053954f5f30feb6ad402dd96f2acadcb2b9f81cb374a9fc73685fd73f81478"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/OrderSummary.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"25fd769f9f622fd4984b58a11442a0a87285874b16c7fc7a72515d5b91fd327e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/QrCodeLink.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd08ed971a8a013f8a81b80687e81e73bbd6747dc73cbe9d31654c0ebd16d5b7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/photo/usePointerZone.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cab1f227f5bd1e07ac71f5a9ef144390dcebad8ede0cefa83e7d91c1099067ed"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/usePasswordStrength.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e16658fc718c1b0c374d94fc71bd549bc8287ed0d8074feb3e5d3467d893f19e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/style/theme.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a54dec5df55c2dfc8109b00752ef307d690402d863882d1b14a747d74fbcf62"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/App.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3059a86ef2521974099cc92fd0f62ba09368588695f652324ff3f7a6ea25e3b4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useTranslation.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e32c54ca49e0fd8eb5dfdab05e4541f6b1ee3ffbfc7ab429756ec587209b0968"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumListView.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"28d5aaec6fc517dac2f2db67503238e32d82b3509a762ffa2b4012c60d37ed67"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/GalleryUnlock.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8d81a6d45a4babe75fb9abca8c34c6fac5cfa69fc35cae8797dcb8a7a03a54b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumListView.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"597676d54ebdd84abb60ec9ce76039c6c10eba0af126d37e20a8480a309ba9c4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/ThumbFavourite.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"670f195f07d9968c76cd7090c24838ff6d97b780cd1822881a14eb41a7fce9eb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceDuplicateChecker.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"726a2d6b52909f665110ba202575d30c75c255406c6debfe5bd9a17d060d657a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceFlushCache.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"43982dfabcb1b26c6eb4a193d00b51273a690518be65a9e65c32b75fef321d17"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Landing.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5256738a8098c6c1486807608ac83e4c2bd11e344fccaee1c617ac003137ed54"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/settings-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c2c438e0d5213cc83acc03326eccbb9f9ccd3dfbda9a4e36ea693f04259c99c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/InputPassword.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e350fde9070b4d5e16c898c0d8dd455746fa95f0c7560a86b086f1f921210ee"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumThumbPanelList.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f9077a258ce03b9ecffc958023625f9e1e21dae23420dce2e27eddb2bd77f49"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/statistics/PunchCardCaption.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a9c6e4b117be4172034c1972efd47c7246d51ace615dfc76c1e190a1e91a6df"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumThumbPanelList.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"70773759375232eb6b8d8a96fca6071a19528bd592e2f15d703dc262857b6a96"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/CarouselImages.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"804ccd9aca90117407eedd774994cf2894a1f0351d5653214a7b6548ec1a3625"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/diagnostics-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"51dc205453da149217b3fdbc95eedc0ad9f834e737547c855e904bc9f84b6912"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/CarouselImages.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee915f21b4ec19c280aa6a6ea1d5aec3e4c0b53ea0a5470de26374a93d2a53c8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/pagination/PaginationLoadMore.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"803ace0f83f975283d8c138c5e76c115ba3082c3cb692b87a4ce35f27a966c12"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/StatTable.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"da429c2815df4072d64cb9de13757575e16d0983cfb4581e4a7a0cb599d86bd9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/basic/InputText.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f8c6b52ed794eb77c685e10ea41193ed2c3389a1d1ddac8bfe74508d7da5c6d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/SessionExpiredReload.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b5c851b200bfd04acc8d698069bea04615998d92018a4b2db809eb30f89f8f3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/spotlight/useSpotlightNavItems.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffedc3cdb8a7fe000d6abc629a5061637df76ed770d5a9db06a9c32a2232dbd1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useLanguageSwitcher.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"af4f16f1c51cfde9d873283c3eb3a1827f98b5d977e6afd03554280d51600cd6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/loadingIndicator.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e13f79dab1933a12d6781dc129e0f273aa794d219418d5cbc674bb65ca78b276"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/ThumbBuyMe.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f7462d7a07782de7548e3acfab567f5c7afe67c90c0d2db68b7401b39f85aac"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/moderation-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1e36bfafaf3b861e81da5b15b1f98227110afbe25e6b43a70b180e5e270157b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/ThumbBadge.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc536f9c93c10adbf1d85a657bfb8f0a13557fc064b1fcc86ac4f7a395f83382"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/ConfirmModalHost.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b07026cc151043fb640da5bd34a99f52cd5c74c419d1810b19d27443fd4cfea"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/PaymentInProgress.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f10c809ac73ad0009bece8efd0490b07c80d4695c063417548176d79e5ecca2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/TransactionIdLink.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"91579b2291db5a2be5ca64256a218c52f4a37b3414de4e89e168aaefd0273f63"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/photo/photoFlags.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"25c35b5af7eaea61eabf542216578bb9cc028ca5362a0eca8439b4578fe6b66d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/services/track-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8692c3e3984c3adc1f0ae137286b070b3cfc9693cfc5c00e77351eaf44e795ca"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/insights/echarts.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"819790a3d3a2688e09bf89c046b42098b4bcea8f63e240913fef7b0539371aa1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Contact.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"24b916d3bab57cf83ecd9dfd5009bf3320261c5ab28acfc5c9cda6a3f2e2df50"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/ImportState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5aba2700f597cc123bc88bac9c62821722ac32f4367730c4660fd541f18c2b8e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/SelectDrag.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c99a366c848239a70d955f03303a5d940223db8c442817318008f21cf742aa8e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ThumbRatingOverlay.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f880dba3f4b127f3d611e0aa5db380f2231910aaabf45d4fc7247b917faf189"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderStatus.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9f743e53db0d8a4127b1200e9ceb44241a1b38043a98717aff622201a6ff6ac"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/ThumbRatingOverlay.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"28d7a5f55f14e29f41db55d70676b19e1d9f1cdc9020504741985e4d218068f3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/i18n.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7731b0176097e7bcffe273e573359c1a38be71d8419cb9f8ea3656b729539f73"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/usePeopleList.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef5603faf6ac9b367eaa7f04814c22a559e935c645b1ecb759624836dbfcd319"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/face-cluster-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"df09ee2262d48170e859d637b893ff6940682462392eb0a305d7f82eb4b9df59"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/PersonCard.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"863b69dedef37dbc490ed90371de7b5976e7bd9236223d32e00053bc3934385d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/CancelledFailed.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"14d4f537ed932c3d8e141550d62d22de0050f099d90445af05414b313b986cc7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/TransactionIdLink.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8b4abd338c400f338b6ee2d6f18102612613026fd475880174d46d551fd176e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/CancelledFailed.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9b4eaeefd36fdcfeb7b5ac5c9f51baa151d8b5e3e308c70e2effdaf9ce39b7b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useAppToast.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c68ed6bf6550592c7239c817075129037a086dc1883da63125ceb37441cafa3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/PaymentInProgress.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa08ef437bff446e5b26c9c97b297411039b4faee2dfcb1cbd5084416c4d6409"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/searchModule/SearchPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"055d1d7d05162d78cb644541d56fe19fe0833df6b57da196bc71b15998c00e08"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/landing/useLandingAnimation.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9ee36c89cc0733e611c4f6fadc9fcf1188c0a9aa1e537892fe9fe3d9b90b001"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/landing/useLandingTextPosition.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b68d7a22dd7e555743c2929671937f68eeac5b8825d617afe911e4d0583dac7b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/checkout/useStepOffline.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"718ab2852e59175eca62a9c991cac0e009c195965b87a4ae71567c10e026f6f7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/layouts/wasmLayouts.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"95b0817b0894783763eb2a56ec6a2abee6c10e54e58e0216b9044c0758f54820"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/LigtBox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ad8caf46e75dfafc9be7c9ba9823f30c8932f61b17ac0d537c7c5b52648b847"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/OrderDate.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c80b8f3d7594c9e9451fea5cf95c4aaf90e75ad34d4b0f4817df13ed94639fca"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/App.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3735f3e1d997f038371373720b105f55b98135ce5cd0774a41eb267778398daf"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/PersonCard.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"05c82ae2766b2c8c1a30e1233ebca2df8d71dc7b0472caa1da1758db51a2c2ee"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/PlacesSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"93b8ba8d94636362a0eafe6f7bf7ab5e59d4046270ff19760cab5eaf119fe30e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/OrderDate.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f27df32967dccb7b51429d8710867bfce3a6e86d1597c68bbb01ecfab5520bd6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/OrderStatus.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b8ea804ede7549a7983fcd456b751b4076fecb06cd0038a641ba5c284c53bff"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/layouts/useJustify.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d146cb2f86d1e4e63f32b72f7d9d71db61efe5b4122a4bb65982ba8cea15eb2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/checkout/useSteps.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"030ee97ba34e4b0bb21491471b3ff42d0c4b59ad4e593968198a84ae96b356b7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useDocumentTitle.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"489d37a9f61579c3f8f9080305a8e7ba8d243e36572081e63ec2ab0ab3363526"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/diagnostics/ConfigurationsDiagnostics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b76815feb07cde11b6d3282ff10337a5ff0ee592ee2c5a5d0037ab3dffdde07"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/frame/FrameInfoBox.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c8c2800ff25a0e20729bdb632273aab94f6f7344cb2b8f23482f2d44461579e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/tags/tagsRefresher.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee6f93030d33fed77a8b8bdef6fdbb4b8090e44c5bc2c5f17c33d0315bd42981"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/timeline-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a4ca5e5ac2c496ff56c9c6d51f399f6be294d97c3992540a8cab49a8e6b724b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/diagnostics/InfoDiagnostics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6d16b1f58880f660559181b92f71d38b77e04e31a21761708b9d06124a8a87e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/diagnostics/SpaceDiagnostics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"91ffc3de8c2cfab7d4e54e21689e3741bed181ffe5b95b116778cc7efc4e1560"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/insights-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a7293325e8031fac7fe92234b655fbae2c90aafb0920cfedbf7e33d7de74af5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/nsfw-findings-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"32d6e3a060d60e166ac284ca80a52d2fa1077105c7e7552a3a5b002b4eefbffb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/diagnostics/ConfigurationsDiagnostics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab14baa2892b53d03580eb4540d01d90352db73de9ebb0db17664a6c01baa61a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/HeaderEditButton.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c49a17cd1775fc03829520f4dbef0e1f1ce3679aec2d1e9694c3ccf606d5596"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/MapInclude.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c42012bff9425456ffb8884f06fe61f1fb5063396cc120eecfaecab37ef1311"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/SearchHeader.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea48e2f66d296255620fd9a1c5d039e6d11da6cd3117c5ad6d1a8acd0d9d9f21"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/HeaderEditButton.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4679c02c1ea6155dac68be96b7e15fc792204dc124ebd97ae0f93bb1f465fa6d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/MapInclude.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbc48d793bdc15e0bcc91d7524410ccef02cfe5389855a2d7798e4ed0066dce8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/layouts/useGrid.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"693b83c8ba58ec1e368d39ec517356cc2e7dd22aaead6dde55f6e6cdbdf75b22"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/layouts/useMasonry.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"28878c7931725be60f68d04d1a50b098a3e22f8abe926e0621bd540617b43a2c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/layouts/useSquare.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"377938e179e58764e51865e4ca30d0837cf85a417f37d36d78e04a8c1306ca40"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/insights/options/exposure.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d380bf8d344cd44540e06cb6ef8cc9ef3971447ad7bc1639e065437c734820d3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/admin-stats-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d06e43d4781df159457cdbdfb531521a639f0c48b4935d416ab3de97d285824"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/diagnostics/InfoDiagnostics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4244dd4a4ac31bc822fcc72d3e72b00525f328bf81c5f51bf3f546f9300c6a19"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/photo/basePhoto.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8defeda389ba98340e46d7da0027b170776bbcf712ebb5c751feedf0ecdc5884"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/diagnostics/SpaceDiagnostics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"af1be5171931e20122bfc265bd076b72a97f03cfd140071f80d23932269c5c8d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumHeaderImage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"00c6f114fdf8e5bb6aeb0971f67c5f4e9a88bb94b80ccbab021bb4ab714aaad5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/BackLinkButton.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4bca026d6b903a52ac741ab05539aa105732d00a399715fcc8b16409ba3ec96"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/statistics/TotalCard.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2dc04fb8974959c0e67f80ccafbee8a7d396515c87ed0b73b627e3a504707993"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHeaderImage.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b37baf394574bcf8906506fe546a93925365185431b601acd530a9e3c15ce168"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/photo/kenBurnsHover.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a63524dcf6faaa218532dab4fc84ad4c43e53d7427de5b99a9b4cd44097f006"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/flow-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b3ef72a2eaff5772ee7f154c024580ce15ef8b202f7ac233f0278a22cf53921"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/searchModule/SearchPanel.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d84418bd7ffc0bf0653dd1fe083072a52108f9d843b6cf66e5cb3055f722a5b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/statistics/TotalCard.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e0d04f3dbd8bc5d67e60ba601568c752913d888e9f62b13a3f78fabf492345d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/spotlight/useSpotlightLanguageItems.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a56491a96779622dcfe6e594242d790138eda62120a5eb0f7e796a69f69d91a0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/layouts/applyLayoutResult.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"85f6cb5e8dd2d7b8e7618312469a18caaa8d05b62763ac07d690133505a6bd98"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/users-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"63bf5242d32c1b4354d8e7d6d07b2dca2908550ff27bec4bc9e71d05d49ee690"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ThumbBadge.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8955c73090f7d658fcc514b3efe14f22dd8b59d53ba11c1961d2735d13a2a5ef"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/Fieldset.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"76a4485550ddd28304056fe25da2199360b2700bf9061bbe19fc5c8b0d3e8718"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/LoginModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfae4b91aa3fb3edc25eb7f588effc3693f8ccbc21c6821ac2d9d65a402b974a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Home.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ff53a5862bd28877812a552dd5e3db8cefe91aa0934716664bdbec1114b35a9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/photo/motionUrlLoader.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e6d578da0a7b0cf1939f234312671eca9599d898d0d6332845e9b2afa4e4f21"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/spotlight/useSpotlightAlbumItems.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8daa9c039ec6c9f2e0e79f688a75bb01821ee9fade4bc469d98796153cba20af"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/smartAlbum.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"86e0962be703d4e26a16ec211eaca54c0b4e6ee734ea9b62e1ee48dce29189df"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Home.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"be0565a465d8c48ef93d7f4c8960b9708eba7c6dde728babf8bf859e40954d07"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/album-list-v3-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"35817b76996a6b970b6bc5737c814b374edfeb238eea58add3eee5f22e1a77c7"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/statistics-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f29ed4d6b0a4b30ef12a2580a9ec98c8e9ae5f50de12a7be6b1f18c6655a96f1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/NsfwConsentedState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad2c50a0c05bec19fd3dabc020971c964582487ac23716524b9d77856b088152"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/ListBadge.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6602d982312076071a8a1b9a9d03df901320933b5d02138c10265c9c0ee3f3c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/ListBadge.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bd1fedbeb1a36307033d4fdcc13bd0b85689b1033b91477b910d37add7c1ddc"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/DockButton.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ef7952c500fcb2eab2e3bc705fac3180ccfd22c135a47005259c6d84b7aa4f0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/PeopleSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8b1301a9a3c41ef321ebdc68956c6e2a86f96dc66a691d922af821507c3b95d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/LoginModal.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8afc9ccf12fad4cd3db66c593e64e71440f404e996deca92a505c75eb6726493"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/moderationEvents.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"972224668c213425483a9d96848f63f1a3bf2c739129f49aaebea57a30a42247"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/webgl.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"50ddb596bdd47ac3a115e353d06c1e1c14062c0ccb5457086f74fd910a1f8ed4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/jobs-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d92c6480154111c2256c1ff90cefcdeed40bd4b53ae51e7ccc55fa1911be7e59"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/nsfw-detection-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8aa17e126a96b4e6e9539727755b63d230f23520e02e19516a39a44f20b4284"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/InsightsToggle.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"be8a905bcda9c57d4e6ebff901de7cf4baf4f196e82c85c34101817fc9276620"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/aspectRatioNumber.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a578c0460ebc3cecb2945e6dcea53323e2a0231443ee0517d76e61e0a78e5ce4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/albumActions.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1dbfb542927d0b399b172d954bff48334dd97e9f3f7b5f524999557a3d675c97"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumStatistics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8f8c3c711d4348974a510101ad85eecd2e08c648bc17d8d862c295c186205c1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/Blur.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"db84eb7921f625421d848827d86a53cd92cf8f52f9c4a9a340bd602b60be0a5a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/ColourSquare.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b934fb57cd0a087f68ae69d0a6fd6883769acd6f3849136b722a844d6166cdcb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/DockButton.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"84e064ac784172f4007cbbaddec2c1270125d203fa3bb8442f2b54a8df10990d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumStatistics.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"06d973f79f5055f7992c230e32df5dc5962cf6b4f4d794875a243db885650179"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/Blur.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b491f61631370fac74dc9de3f4762940fc3c008e7675e3acb1f6370a6d32e6d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/loading/LoadingProgress.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"01b43f8eb4a67a4a6ae6a52e994f7f9e595a7a52d25b7662868200f411cf8be4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/resolveCssLengthPx.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5067fcd365eb692bfc694c6f30c920e56abec0a6317f22b7bfe66888eb92ba97"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/propagateEvents.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bc3866e1fc5eb4b60dbf753e9e95ed35ecc2f3e4dbe0f24668791fce37bf8fb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/admin-setup-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"86e7c1d2485f1a4008f817cb3355a6051479fdbbe1b19cb61d3131e2809ebbbf"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/nsfw-config-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"485f189f14c45a5ce8d776a4f138b4fb865bf0f5feea6755087367ae8e5f727b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/security-advisories-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd9cc2d4fee22d549822714b4ed311d11d8556324507667d33bdfa6df4a88cbd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/LeftMenuState.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"222bbb379ed3b66da60c05d59d06106cc3a4ad1f1fbd72b2e1ca385fb7be7143"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/admin/AdminStatTile.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"376041887c76279e86177330615fa1a52a381d1b472c9feb90a4fa12572dc1b6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/icons/MiniIcon.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb630be603278c91dea52bbec06e97fe89cac367890a4d2f61a77ec875c47a96"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/loading/LoadingProgress.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"da09b97511f11b705f047ce88b8ec57b8c01dd1c8574410d0a584a24eb624720"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/ColourSquare.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"639f939bcb9da5b0ef99323bdadb4a1dbcde68b11e8bc7ae98cb40d7b69a4970"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/BackLinkButton.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"222170be69a685a79d666ce0f81b8b88c74ed7a8d10e0316b16504a9d8f67339"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/icons/MiniIcon.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"89203934589dd5299c8ffdf4a790a2091afa0ebb8d59f63660ca602d38d76b75"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/icons/PiMiniIcon.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"090266813d1d084f11ca2eea8832aeb9fb0b3bb8778cbcd4c283da148429c7a1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/layouts/wasmLayouts.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"153137f85ffb28b30a58ed69d2aeaf7e28e940bf83a2efb97b86c2bd9eb6e4d3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/GoBack.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"390a8b4d7114d4f061790ec9ac35cac53f83dfcb02e84e541c08c0fb69be8c80"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/icons/PiMiniIcon.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"22a54d757705efdee2af987dffce1cb1a2135ee0e059749d599a9d58e2cc9dd0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/icons/SETag.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"17e66d88758b973ce83a4493018191c7adb1cd8d1db7d95a8bbf1a866e03f633"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/InsightsSection.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8bb03f6c847636531dc66b3307e944bb86cbf67a8d87cb3ddc386410024a73c8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/ratio.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"beeb7f0535623061279a52bef6a40f99a377e86155315cac73efad4c977a3f2c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/icons/SETag.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"52a6e98fb8b05730a4cad4133446aef92ae721360db98deeed7680a81ed78157"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/GoBack.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a590320e603c78778c50b6d98436abe4611c5f1dad5949add94c571aee8d5cd0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/headers/OpenLeftMenu.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab4cb3482ff26986ff1642d9f334e4a35a8d0db26892c3fd99b2ed5c3346aa07"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/utils/watermarkHelpers.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a91c24263c31bc18635c59ad8fab04aa7e9c1cadfb65bac14e2ef54078d9c676"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/headers/OpenLeftMenu.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"555587f0f9b33b8d99cdf2f2bb5e406916c62e02a578d7858b7b1571fe66a20c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/gallery-password-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"29822101ada59b09008f1be1b4e76392859f6a9adf0ad2d930264eaaf65fb0cd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/photo-faces-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f06e9f41476bb9a538a82abcc5bcf7905ce892fdc4026366b3bd658f4d7a64a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/photo-nsfw-detections-service.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ae1da601fcee22c2296e02c6fb95a3798416dab4e10879c531ac20a945e84ac"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/UsernameEmail.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"00270ddd3ca2b28462deadaf28a639b7b6d8e60b1e163a03dec6f44911769e65"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumExpertModeToggle.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb64e3848ecdcd9975200d095e105ac60f5e90efeac6333e3b3d76e2c046f9f3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/UsernameEmail.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d36af6dde142ee4225bb0fb661abac81f1c61f323b9b5cca5d4e56298d7029f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/InsightsChart.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"68d581b33ced489aebcab1971fa522583cfcf7e5175c1e0bfa65da634d50ec1e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/insights/InsightsStat.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"47c5858548e19d2a4c0661870ebe1509827716d78544c34928fa62e902a2b2bd"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/ResetDir.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"287640c46e455a406159bce0c9ae2881f47344915d66f0f8a0e0cc882bec5207"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/landing/LandingBackdrop.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ecde58e38be878f218269e366665901d2b0e05cc3d6f6269e67b00dda063eec2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/d.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9888f6183f8272ec0449c20efe2c3b1329d855f8a1cb8db28a7a1784cda3c760"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/ResetField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b674cfbba7d2415e463ad682370b7daedbcf30e2fd6cbc04fbba99d47a65e9b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/mini/LeftWarn.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"68cd4498d19f681654c55aa17aa01e548ee2657eac9f5f4c5cc40ed892fc4641"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/mini/RightWarn.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4deb028ca75950dd1c455433bfaa5f3cd0c904623a2e81e286484f7147a2d519"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Placeholder.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f92bbccb73006538bb639eee46a20507dff8314784e30b1e55ce8c0e6dd243f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/ResetField.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"940bd4430b7e264ba343b4915051b68ec02dc7984e091b98a0615c2524fd1897"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/AlbumCardSkeletonV3.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3caea8d8c0dea88d2ead8be66c33b2fd8e1da2ef812205062215a606772f2a2a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceRow.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea55e95fc0d526625e41ef5f5760a96ec9807566134a99dc22e90857667a0c4f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/mini/LeftWarn.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed3afa1f768b35a16530cebd76a890943981443fd105cc3288cb97effb34ae7b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/mini/RightWarn.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6311d1cd1a6944e90fd0beea55259b49c6ad4a67585b816f0da96bfe7d007515"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Placeholder.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"af9b359e05793d02ad0ba5f51584d335f1e1f01966862f7c19ef4fae070ea96d"}},{"ruleId":"R5","level":"warning","message":{"text":"Dependency Freshness: 49 outdated package(s); JS/npm CVEs scored in D30"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7de98450603a813bc7a991bc6e60f440c1deac6f9c9bfd4d0da057afed869bcf"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~205 LoC): no import path from any entry point (8 application, 7 tooling, 4 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/Password.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d551bd6be606042ee27e00ad4f60dd1d54f57ba7f61b79958f629fc04fe90b28"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~133 LoC): no import path from any entry point (8 application, 7 tooling, 4 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/pagination/usePagination.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"371d2de4d9179620670b87eed9a2f0c174fc9032d7f3557367d176ee8c152470"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~95 LoC): no import path from any entry point (8 application, 7 tooling, 4 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/sharing/CreateSharing.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"040cede70030b7780403fe6186855fc0e0f89f01b7e480517c22e08b4b989b3a"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~87 LoC): no import path from any entry point (8 application, 7 tooling, 4 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/PurchasablesList.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b58813428c609954f318cd9947d4f2712cd9c53c6b3d87852bde9ee414180ca"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~65 LoC): no import path from any entry point (8 application, 7 tooling, 4 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/webshop/PurchasablesList.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9fe9795e99db513dcbe8af92a77a28b92c127936ba8d2dad32116f2aaa8c8d7"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~38 LoC): no import path from any entry point (8 application, 7 tooling, 4 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/card/cardTypes.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"145617a0469a4ca79fd2edbcc5881b11e157ae540f963cf098be2feb1ad151a6"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~36 LoC): no import path from any entry point (8 application, 7 tooling, 4 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceDuplicateChecker.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf150faa8fbb3d9b75b15b2548f0fe5a03c273549d02bd33a6990612fce964b7"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~23 LoC): no import path from any entry point (8 application, 7 tooling, 4 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/photo/basePhoto.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"be5720a7c87907bea29ac5361a31502380430c3eadd75cd115dda5c20e9a3a29"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~8 LoC): no import path from any entry point (8 application, 7 tooling, 4 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/card/images.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eaf6749c009ab34bf9340976d05235ea82d8ce1520c016bdcbae2be830ea5df8"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027calculateColumns\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in resources/js/embed/main.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in resources/js/embed/main.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/utils/columns.ts"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3b54fa0b0d1f2f01d3245b1cb1b400b13ba3611d6c965a38767ac27ecf4697e"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027calculateColumnsFromBreakpoints\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in resources/js/embed/main.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in resources/js/embed/main.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/utils/columns.ts"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"180f9cb9990d5e468279fb2f5c8cd7e921c10925db002d8e1d629f2f113a4b0f"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027distributeColumnWidths\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in resources/js/embed/main.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in resources/js/embed/main.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/utils/columns.ts"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"f688d318641eadef2ac94be1a7ec83b616aff2659ee14e6b60a1a5b242811161"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027calculateJustifiedRowHeight\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in resources/js/embed/main.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in resources/js/embed/main.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/embed/utils/columns.ts"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"7339868b9bbce1d81d9228c5542728784ac2e4b5c7fac844822b7c5eb5b7dee9"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027PhotoFavourite\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/FavouriteState.ts"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"54a462023accee1762968c55ef3a6e3d30a546f336d3302adacfec528ffc23a6"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027FlowStateStore\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/FlowState.ts"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bd3ae7a2625b54031d3a60944d1af9137f4983cf827d71be5eebfe8d877a5f0"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027ImportState\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/ImportState.ts"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"783f05ab56fae7ed1b18fee70ddfaf9251fc50d2cdeab458d164bf1078d38e46"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027MapStore\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/MapState.ts"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"218b73e5f57702f589a669e42c675782f7a91d370a2ce3d62b9137722396ed5e"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027NsfwConsentedStore\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/NsfwConsentedState.ts"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"461279ea1cb6335c614e293dc3a0c9a4786dc9a109b3f2476674aee9ba26d2e0"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027SearchStore\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/SearchState.ts"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"94be56a104976697c4bd0a5e3dc883cd54cdb01107e187e7b7cc2620729f0939"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027ShopManagementStateStore\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/ShopManagement.ts"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"04329bb4d273948d62317a0dc3997876449591e1e6964d48840b2de44d39143b"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027TagStore\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/TagState.ts"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"30ddba47cfc7026b548575f27cc4b30c6b251dd54c6b4ad17439868e5eb34c8d"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027isApple\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/utils/keybindings-utils.ts"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"99aa3871ac569773425c9c0b5d9442af75cc93f07fba172769c8d5c68c7e116b"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027vsprintf\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/utils/sprintf.ts"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"541b436fca7748fc577e2019dba76ebaf9b384d89b6101ed38dbedfc5b8a59e2"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027resolveBreakpoint\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/albumTileWidth.ts"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6821808eb4158d8613b2816ff206351542d2316b7054863d768433c833ef7a2"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027categorySymbol\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/utils/insights/options/timeline.ts"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c5e73f9642f4c4908243bee88301b2169fb8d6cbbede2d04fb44984f0b1c5be"}},{"ruleId":"R8","level":"error","message":{"text":"Unlisted import \u0027@dayflow/blossom-color-picker\u0027: Imported but not declared in any reachable package.json \u2014 installs work only by hoisting accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/ColorField.vue"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0d67c6eee6120af0ee348b86c488bf084e314feadbbe744ca73517c7b43f3b7"}},{"ruleId":"R8","level":"error","message":{"text":"Unlisted import \u0027@iconify/vue\u0027: Imported but not declared in any reachable package.json \u2014 installs work only by hoisting accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/icons.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"04e0f4d27e77be9cc86815d1a829649ab5df5997b6381be50e07879e7454191d"}},{"ruleId":"R8","level":"warning","message":{"text":"Unlisted import \u0027@primevue/core\u0027: Imported only as a TYPE and declared in no reachable package.json. The import is erased at compile time, so nothing is installed and no runtime resolution depends on it \u2014 but type-checking a clean clone will fail. Declare the typings it resolves through (or the package itself) in the owning package.json."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/basic/InputPassword.vue"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4258ebda97692a7c81712816034c2b5c96e65dc4ccf3502c9bf702ff9229197"}},{"ruleId":"R8","level":"warning","message":{"text":"Unused dependency \u0027@fortawesome/fontawesome-free\u0027: Declared in the root package.json but never imported anywhere in that package or its workspace members \u2014 no static import reaches it. Usually that is dead weight and attack surface, but two shapes are indistinguishable from source and are NOT dead: an optional or native peer that another dependency loads dynamically at runtime, and a package a build, docs or test step installs and invokes separately. Confirm which of the three this is before removing it."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f2c8ff4a64d9fbe01c1d8dbea39d99c2409055416018bb0fb72ea30665544f36"}},{"ruleId":"R8","level":"warning","message":{"text":"Unused dependency \u0027@mollie/api-client\u0027: Declared in the root package.json but never imported anywhere in that package or its workspace members \u2014 no static import reaches it. Usually that is dead weight and attack surface, but two shapes are indistinguishable from source and are NOT dead: an optional or native peer that another dependency loads dynamically at runtime, and a package a build, docs or test step installs and invokes separately. Confirm which of the three this is before removing it."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"8d6987f556204ab9803e0e8712735e86500fd2d850678a4bc018aeeea1cbb032"}},{"ruleId":"R8","level":"warning","message":{"text":"Unused dependency \u0027@stripe/stripe-js\u0027: Declared in the root package.json but never imported anywhere in that package or its workspace members \u2014 no static import reaches it. Usually that is dead weight and attack surface, but two shapes are indistinguishable from source and are NOT dead: an optional or native peer that another dependency loads dynamically at runtime, and a package a build, docs or test step installs and invokes separately. Confirm which of the three this is before removing it."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"266f5ae8b3c7fdc7ffc15b7b9e0c2f60737badc485969979016c005539d9d016"}},{"ruleId":"R9","level":"error","message":{"text":"Import cycle (2 files): resources/js/composables/album/folderDrop.ts \u2192 resources/js/composables/album/uploadEvents.ts \u2192 resources/js/composables/album/folderDrop.ts"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/folderDrop.ts"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"9297a3c5ede2b5cd567e7c8b963310ecee6234eea2d73f232eef0a414474f9d3"}},{"ruleId":"R9","level":"error","message":{"text":"Import cycle (2 files): resources/js/layouts/PhotoLayout.ts \u2192 resources/js/layouts/useGrid.ts \u2192 resources/js/layouts/PhotoLayout.ts (one verified cycle inside a mutually-dependent group of 3 files)"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/PhotoLayout.ts"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad74659450bf9e4ca14db0b73509fc66ae7ec4b8c32ba4ad67e4814ce103c8cd"}},{"ruleId":"R9","level":"error","message":{"text":"Import cycle (2 files): resources/js/v8/layouts/PhotoLayout.ts \u2192 resources/js/v8/layouts/useGrid.ts \u2192 resources/js/v8/layouts/PhotoLayout.ts (one verified cycle inside a mutually-dependent group of 3 files)"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/layouts/PhotoLayout.ts"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"94c39a691cfc626ee45681343b2a4e9ff558c4249d346985cc2eb1510d5cd3be"}},{"ruleId":"S1","level":"warning","message":{"text":"Third-party script without Subresource Integrity: \u0060https://js.mollie.com/v1/mollie.js\u0060 is executed by this page with no Subresource Integrity. Whoever can answer that request \u2014 the CDN, anyone who compromises it, anyone on the network path \u2014 runs arbitrary script in this page\u0027s origin, with its session. The URL also names no version, so it resolves to whatever that origin serves at fetch time \u2014 the executed bytes can change with nobody touching this repository."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/views/components/webshop.blade.php"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ec96ff87c52bf3e0918bfa517bdde276607f52878bd693f7572f3fc8c398077"}},{"ruleId":"S1","level":"note","message":{"text":"No security response headers detected: None of the 11 security response headers the OWASP Secure Headers Project recommends (Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, \u2026) is configured \u2014 defense in depth, even when a reverse proxy could set them. This is reported because \u0060nginx.conf\u0060 is committed to this repository and declares the server that serves it, so the configuration that would carry these headers is in this repository and was read in full. (\u22122.0 on this card.)"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docker/nginx.conf"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d1145a1a686a832a906ad66bbb0ed730d42ecd93ee0711e9758821687c54020"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060!(route.name as string).includes(\u0022timeline\u0022) \u0026\u0026 is_timeline_page_enabled.value\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/leftMenu.ts, resources/js/v8/composables/contextMenus/leftMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1d5056c4e4d1b0891e6c6f7b1d1572e7f2a11d2824002b2f008ed61b5e401d1"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060!(route.name as string).startsWith(\u0022gallery\u0022) \u0026\u0026 user.value?.id === null\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/leftMenu.ts, resources/js/v8/composables/contextMenus/leftMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"9cb48d9e2eeffdbb9f6f1ff4044e4e5d3e646a0a3012523e5ae86354d307a869"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060!gesture.moved \u0026\u0026 !isTap(gesture.start, point, 1)\u0060 appears character-identically in 2 files \u2014 resources/js/v8/composables/usePanZoom.ts, resources/js/v8/composables/useSphereViewer.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/usePanZoom.ts"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"3799113f8e658620fffff50cfcb9f8d6f1455267c913857e7efd8916ddb3d201"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060accumulator \u0026\u0026 currentValue.rights.can_delete\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/contextMenu.ts, resources/js/v8/composables/contextMenus/contextMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"38b09e62170a2e6744587fbf48693f4bc92fe851edf30391e1d3620f7cf6d280"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060accumulator \u0026\u0026 currentValue.rights.can_download\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/contextMenu.ts, resources/js/v8/composables/contextMenus/contextMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8208c66618ae6e5bb9510e76342daf18bd33232bf827823166f2517df273451"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060accumulator \u0026\u0026 currentValue.rights.can_move\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/contextMenu.ts, resources/js/v8/composables/contextMenus/contextMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"f82d79eca36dd258c0291ab3bcfc42d56500af04a75fe754578c786cccac01b9"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060albumStore.rights?.can_import_from_server \u0026\u0026 albumStore.config?.is_model_album\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/contextMenuAlbumAdd.ts, resources/js/v8/composables/contextMenus/contextMenuAlbumAdd.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenuAlbumAdd.ts"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ebcd47b0179c7149270f35a2330195c8aa0bd6e9cf9b45d1a9e4d16f5681c7c"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060album_id === undefined || album_id === ALL\u0060 appears character-identically in 2 files \u2014 resources/js/services/metrics-service.ts, resources/js/services/search-service.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/metrics-service.ts"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"f675ad898199b85ff44cdecf9d6a33204cea12231081be4b6313e8a867cf25d3"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060albums.value === undefined || originalAlbums.value === undefined\u0060 appears character-identically in 2 files \u2014 resources/js/composables/album/treeOperations.ts, resources/js/v8/composables/album/treeOperations.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/treeOperations.ts"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ff6dedc4508d4036903bc4be83e3c8a0eedc55c387e05702f3382cbd57349bd"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060error.response \u0026\u0026 error.response.status === 401\u0060 appears character-identically in 2 files \u2014 resources/js/stores/AlbumState.ts, resources/js/stores/AlbumsState.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumState.ts"},"region":{"startLine":205}}}],"partialFingerprints":{"codehealthFindingId/v1":"59544302167b66942504fb461889aa2072970ff74f24d10c48c47b3ad0aad770"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060event.pointerType === \u0022mouse\u0022 \u0026\u0026 event.button !== 0\u0060 appears character-identically in 2 files \u2014 resources/js/v8/composables/usePanZoom.ts, resources/js/v8/composables/useSphereViewer.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/usePanZoom.ts"},"region":{"startLine":251}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9760906e674b29f50e20a69d96bd5b605f0b618246cd675cefd01f816d18325"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060item.if === undefined || item.if !== false\u0060 appears character-identically in 4 files \u2014 resources/js/composables/contextMenus/contextMenuAlbumAdd.ts, resources/js/composables/contextMenus/contextMenuAlbumsAdd.ts, resources/js/v8/composables/contextMenus/contextMenuAlbumAdd.ts, resources/js/v8/composables/contextMenus/contextMenuAlbumsAdd.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenuAlbumAdd.ts"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3e711c88569617543fb67f60636900b29352845f523ad922ab74e00a2e694ae"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060items[i].type.indexOf(\u0022image\u0022) !== -1 || items[i].type.indexOf(\u0022video\u0022) !== -1\u0060 appears character-identically in 2 files \u2014 resources/js/composables/album/uploadEvents.ts, resources/js/v8/composables/album/uploadEvents.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/uploadEvents.ts"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"6098ed34994b78ae02a666978eb5b8020ba3f367799609f121ac913ff8cf681c"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060photoListing === null || layoutState.config === undefined\u0060 appears character-identically in 2 files \u2014 resources/js/layouts/PhotoLayout.ts, resources/js/v8/layouts/PhotoLayout.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/layouts/PhotoLayout.ts"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfde825396507f46b751eb34f979b276d567294fbf20bd62f68b1ed33b32feb9"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060r.id !== target.id \u0026\u0026 r._lft \u003C target._lft \u0026\u0026 r._rgt \u003E target._rgt\u0060 appears character-identically in 2 files \u2014 resources/js/stores/AlbumListState.ts, resources/js/v8/composables/album/albumNavTree.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/stores/AlbumListState.ts"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e647e7b6db2a3b533bc60abed8bd9a01b976de6534c8f9de23dec6f8fd4ce06"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060rights.value.modules.is_contact_enabled \u0026\u0026 !canSeeAdmin.value\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/leftMenu.ts, resources/js/v8/composables/contextMenus/leftMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a28f8374a1fb88ef8f23f20fb933904ceba5a66a26888b78284ec25919afee9"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060rights.value.modules.is_contact_enabled \u0026\u0026 canSeeAdmin.value\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/leftMenu.ts, resources/js/v8/composables/contextMenus/leftMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cd5b9c4de250f12d729bfb92e5c9293c7db80d6f4b847c3cff043b7f9c0a144"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060rights.value?.settings.can_edit || rights.value?.user_management.can_edit || rights.value?.settings.can_see_diagnostics || rights.value?.set\u2026\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/leftMenu.ts, resources/js/v8/composables/contextMenus/leftMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/leftMenu.ts"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4efd8f86881c7ab39d59302f74ce467304671c64059499da8b81b5b2b62dc36"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060selectors.album !== undefined \u0026\u0026 selectors.album.value !== undefined \u0026\u0026 (selectors.config?.value?.is_model_album === true || albumStore.tagA\u2026\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/contextMenu.ts, resources/js/v8/composables/contextMenus/contextMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc0dcd979c4047876c351a0bb5a674d428eeb41b303d368a55480edc7f8b44e8"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060selectors.config?.value?.is_model_album === true \u0026\u0026 selectors.album !== undefined \u0026\u0026 selectors.album.value !== undefined\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/contextMenu.ts, resources/js/v8/composables/contextMenus/contextMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"9cda6bf10828a33ec71c8fc19944e5c17be3b5c3b6f48ee7151128647a4f076a"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060selectors.selectedAlbum !== undefined \u0026\u0026 selectors.selectedAlbum.value !== undefined\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/contextMenu.ts, resources/js/v8/composables/contextMenus/contextMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1e69398938919d2b747614982ccdca7d81d9ed31061da0760dfb55e28039e5e"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060selectors.selectedAlbums !== undefined \u0026\u0026 selectors.selectedAlbums.value.length \u003E 1\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/contextMenu.ts, resources/js/v8/composables/contextMenus/contextMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"cde1f889a660458e6c8bdf5aff7a36dc8fb5e4853f5b44d078eda25e8e4cbc65"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060selectors.selectedPhoto !== undefined \u0026\u0026 selectors.selectedPhoto.value !== undefined\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/contextMenu.ts, resources/js/v8/composables/contextMenus/contextMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"5190999db57014ecb59ce31d16b2ceaff9de1ddb136d5cc95d56d06930223b9b"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060selectors.selectedPhotos !== undefined \u0026\u0026 selectors.selectedPhotos.value.length \u003E 1\u0060 appears character-identically in 2 files \u2014 resources/js/composables/contextMenus/contextMenu.ts, resources/js/v8/composables/contextMenus/contextMenu.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/contextMenus/contextMenu.ts"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"527e0bd2dee2b23b9edba1c39d52c8fd7d81a0390dda647212bfc37da97177ad"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060upload_config.value !== undefined \u0026\u0026 upload_config.value.folder_upload_enabled === true \u0026\u0026 e.dataTransfer.items \u0026\u0026 hasDirectoryEntry(e.dataT\u2026\u0060 appears character-identically in 2 files \u2014 resources/js/composables/album/uploadEvents.ts, resources/js/v8/composables/album/uploadEvents.ts. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/album/uploadEvents.ts"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"bff9864a46f73995c97c6125ca3460d7343a09b3232d9abb2e1e93d4cf8313bd"}},{"ruleId":"X19","level":"warning","message":{"text":"Process-global state is restored only on the happy path: \u0060putSourceIntoFinalDestination\u0060 changes state that belongs to the whole PROCESS and changes it back at the end of the same body \u2014 the process umask (changed at line 84, put back at line 86) \u2014 which says the change was meant to last no longer than this call. But the restore is an ordinary statement on the straight-line path, not a \u0060finally\u0060, so it is skipped by any exception thrown in between: PHP then keeps the overwritten value for the rest of the request \u2014 and in a CLI command, a queue worker or a long-running server (Octane, Swoole, RoadRunner, FrankenPHP) for the rest of the process\u0027s life \u2014 and every later relative path, child-process launch, date, number format, XML parse or error report in ANY class reads it. That failure is silent and remote from its cause: the function that breaks is not the function that moved the value. The durable fix is not to widen the restore but to stop mutating the global: pass the value to the operation that needs it \u2014 \u0060cwd\u0060 and \u0060env\u0060 to Symfony \u0060Process\u0060 (\u0060new Process($command, $cwd, $env)\u0060) or \u0060proc_open($command, $spec, $pipes, $cwd, $env)\u0060, absolute paths instead of \u0060chdir\u0060, an explicit \u0060DateTimeZone\u0060 or locale to \u0060DateTimeImmutable\u0060/\u0060IntlDateFormatter\u0060/\u0060NumberFormatter\u0060, an explicit encoding to the \u0060mb_*\u0060 call, \u0060LIBXML_NOERROR\u0060/\u0060libxml_get_errors\u0060 handling in one place. Where the global genuinely must move, wrap it \u0060try\u0060/\u0060finally\u0060 so the restore runs on every path."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/Pipes/Standalone/PlacePhoto.php"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd443f34cb45c32a0627697f77f583dc77f38d5f99ae05fc45d595518ded9d1a"}},{"ruleId":"X19","level":"warning","message":{"text":"Process-global state is restored only on the happy path: \u0060handle\u0060 changes state that belongs to the whole PROCESS and changes it back at the end of the same body \u2014 the process umask (changed at line 84, put back at line 86) \u2014 which says the change was meant to last no longer than this call. But the restore is an ordinary statement on the straight-line path, not a \u0060finally\u0060, so it is skipped by any exception thrown in between: PHP then keeps the overwritten value for the rest of the request \u2014 and in a CLI command, a queue worker or a long-running server (Octane, Swoole, RoadRunner, FrankenPHP) for the rest of the process\u0027s life \u2014 and every later relative path, child-process launch, date, number format, XML parse or error report in ANY class reads it. That failure is silent and remote from its cause: the function that breaks is not the function that moved the value. The durable fix is not to widen the restore but to stop mutating the global: pass the value to the operation that needs it \u2014 \u0060cwd\u0060 and \u0060env\u0060 to Symfony \u0060Process\u0060 (\u0060new Process($command, $cwd, $env)\u0060) or \u0060proc_open($command, $spec, $pipes, $cwd, $env)\u0060, absolute paths instead of \u0060chdir\u0060, an explicit \u0060DateTimeZone\u0060 or locale to \u0060DateTimeImmutable\u0060/\u0060IntlDateFormatter\u0060/\u0060NumberFormatter\u0060, an explicit encoding to the \u0060mb_*\u0060 call, \u0060LIBXML_NOERROR\u0060/\u0060libxml_get_errors\u0060 handling in one place. Where the global genuinely must move, wrap it \u0060try\u0060/\u0060finally\u0060 so the restore runs on every path."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/Pipes/VideoPartner/PlaceVideo.php"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"62dfcb1a46db06fcbed8d8471912f4054dbd9e2095d8a424eb985d38c5e651c5"}},{"ruleId":"X19","level":"warning","message":{"text":"Process-global state is restored only on the happy path: \u0060write\u0060 changes state that belongs to the whole PROCESS and changes it back at the end of the same body \u2014 the process umask (changed at line 83, put back at line 87) \u2014 which says the change was meant to last no longer than this call. But the restore is an ordinary statement on the straight-line path, not a \u0060finally\u0060, so it is skipped by any exception thrown in between: PHP then keeps the overwritten value for the rest of the request \u2014 and in a CLI command, a queue worker or a long-running server (Octane, Swoole, RoadRunner, FrankenPHP) for the rest of the process\u0027s life \u2014 and every later relative path, child-process launch, date, number format, XML parse or error report in ANY class reads it. That failure is silent and remote from its cause: the function that breaks is not the function that moved the value. The durable fix is not to widen the restore but to stop mutating the global: pass the value to the operation that needs it \u2014 \u0060cwd\u0060 and \u0060env\u0060 to Symfony \u0060Process\u0060 (\u0060new Process($command, $cwd, $env)\u0060) or \u0060proc_open($command, $spec, $pipes, $cwd, $env)\u0060, absolute paths instead of \u0060chdir\u0060, an explicit \u0060DateTimeZone\u0060 or locale to \u0060DateTimeImmutable\u0060/\u0060IntlDateFormatter\u0060/\u0060NumberFormatter\u0060, an explicit encoding to the \u0060mb_*\u0060 call, \u0060LIBXML_NOERROR\u0060/\u0060libxml_get_errors\u0060 handling in one place. Where the global genuinely must move, wrap it \u0060try\u0060/\u0060finally\u0060 so the restore runs on every path."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Image/Files/FlysystemFile.php"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e76972c8f6ba6e4a297001ff1a4c8432c23713bd4d5cf5c05b7868f04fdae36"}},{"ruleId":"X2","level":"note","message":{"text":"Not all async functions that make a request accept an AbortSignal: Only 0/3 async functions that make a cancellable request (fetch, axios, ky, ofetch) accept an AbortSignal or pass one on, so a request keeps running after whatever wanted it has given up \u2014 a page navigated away from, an unmounted component, a timed-out job. Take a \u0060signal\u0060 (or an options object that carries one) and hand it to the request; where nothing could ever cancel the call, omitting it is a deliberate choice \u2014 judge against how the function is used."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"bd89d014f84408f7063269aa5892ba3df7c9af3e981ecfb0752c5731bc62d406"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: batchAssign: \u0060batchAssign\u0060 awaits \u0060axios.post(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060axios.post(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/face-batch-service.ts"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba1964d78be623842000457bb3f175fe74c58344181904f3f5234c5394f98be2"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: batchUnassign: \u0060batchUnassign\u0060 awaits \u0060axios.post(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060axios.post(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/face-batch-service.ts"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"3863d91db22a686f64916ed0be4ef85d28a25a385475a6feb9f6a7bc4b93fb95"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: batchUnassignByPhotos: \u0060batchUnassignByPhotos\u0060 awaits \u0060axios.post(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060axios.post(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/services/face-batch-service.ts"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"678c8e16c2d696ebe98cdb383721d4e03ecdd1e5c79c845ce6472def6ebdeeec"}},{"ruleId":"X23","level":"note","message":{"text":"Diagnostic log message is built whether or not it is wanted: \u0060debug\u0060 at line 308 is called with an argument built by \u0060array_keys($result)\u0060 (line 312), whose cost grows with the collection it walks. PHP evaluates a call\u0027s arguments BEFORE entering the method, so that join/projection runs in full every time this line is reached \u2014 and then the level check inside the logger discards the string it produced, because debug is a level a shipped configuration normally leaves off. Nothing here decides beforehand whether the message is wanted: no \u0060isHandling\u0060 test, no debug flag, and no placeholder context array that lets the logger build the text only when the level is on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Auth/LdapService.php"},"region":{"startLine":308}}}],"partialFingerprints":{"codehealthFindingId/v1":"49a909a67c288c9ce1cae7b17adc434ff8e5ece605539512441e994d1ccbfdf2"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027statistics.metrics.preview_text\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/LiveMetrics.vue"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3ab132bf4351be15ae30ce6c81a8dc7e95b8ffeb74cc6661608074f82fd5416"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060printSingular(item)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/LiveMetrics.vue"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fd14887b442923ed5e75f8fd3ea517fa586498575a27af5f79d2488f47a5e51"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060printPlural(item)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/LiveMetrics.vue"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"d244bb88b2523a49f2baf00dff7ef91cff52d650f48f9670d08d0bab15da1c80"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060photoStore.photo.preformatted.description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/PhotoDetails.vue"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d1520c3ffe7aaf3c5359e89c957365fe5a714f6f354f603197ddd8c4b714065"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf($t(\u0027gallery.photo.edit.set_taken_at_info\u0027), \u0027\u003Cspan class=\\\u0027text-warning-600\\\u0027\u003E*\u003C/span\u003E\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/drawers/PhotoEdit.vue"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"90a7193651c42deb03f1216ed01b37db52d6b5a9b11e0d75891efe6c6bbb6895"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027people.face_recognition_warning.example_body\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/faceRecog/FaceRecognitionWarning.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"26aebb2ebf1cafba31a2c352e4bab99f61b854113d4a226a361230a5b9e4a5a2"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027people.face_recognition_warning.no_liability\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/faceRecog/FaceRecognitionWarning.vue"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"848bf4bb1a8098577b5f7215e319271d620091d8c6d7db85d47d2ce0de10fe2e"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060footerData.footer_additional_text\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/GalleryFooter.vue"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"f764b732d77e07aba5b5eda4ddc70ae87c4e7d476f1c60b3ee352a934a018ebc"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.footerData.footer_additional_text\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/footers/LandingFooter.vue"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"40880b1661e1155bc88d564b0f2e4b87f65d548d44d7f04ae78cc6c70657bd9b"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027dialogs.visibility.upload_expl\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumVisibility.vue"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"55667c33a59540c6c36828d4aadc2107a44acbd709fb821dcec6af5e461e8e0c"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027dialogs.visibility.password_prop_not_compatible\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/AlbumVisibility.vue"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"41a311f3f31bb6f4ebd50b870152f562739fb944d7f836fbdee388cf48e21944"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027sharing.propagate_help\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/ConfirmSharingDialog.vue"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff30e47f4788c509da40fc2e1c338c9fc952a31d140f5ff05dca56c061e53357"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027sharing.propagate_default\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/ConfirmSharingDialog.vue"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"db97df8f800029a7c17a1e2a71c10e875ab73d4d623af20acd90ba4e712f113b"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027sharing.propagate_overwrite\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/ConfirmSharingDialog.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"000f212a12ae5757122cb946bcd3e25d19f28acf34b4aa76fbc1fc48b8df1014"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060trans(\u0022dialogs.embed_code.preview_failed\u0022)\u0060 is text this program did not author, and it is written into the text of an element through \u0060innerHTML\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/album/EmbedCodeDialog.vue"},"region":{"startLine":389}}}],"partialFingerprints":{"codehealthFindingId/v1":"150819a2edb8dd3135dbd9c621c7aedb7848032253386a165c7c27f47b264ec0"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.label ?? tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/BoolField.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"210479597d8093375e279dbad6d6e0fab798bb7dcc66aa084e60fac5cfa0d3ec"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.details ?? tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/BoolField.vue"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"243d2aee5ae8849c3ebca8d908511f9ffc149705e13350e652be8abea48dbefc"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/NumberField.vue"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7504b4ad49d039cd24eba9410b7a4d79b07add1ee384da113430770e037819f"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/OldField.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"94f4661362d230e65ca533fea0308b24b14aa4f3dc67871221655e404b5e946e"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/PasswordField.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fc016518f9c3dcba90c91d8921126fbe8f36d506db2aea56e1d98acb7f9238a"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/PasswordField.vue"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2b527e4f1f8c27a3da6dc30c3fb52a881081ea232fb178c6486598ed0b06fd4"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.label ?? tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SelectField.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1e3aaa88ed13c8d6c8cc4e90a5028224efd766f349efec276f17bf8bc980daa"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.label ?? tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SelectLang.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"3db3e1a8c1ce0461cb8ee93a1f7a8596e46c1b1700f883852d7e0b5a14b43148"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.label ?? tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SelectOptionsField.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"332227593724e5c11bd5b75a78783e93d47b783f7b16764ce5f9e24cb90c5f16"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.details ?? tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SelectOptionsField.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"e61c5287d8b1c0ea6291ef9439d18380cbd49b5836c25a66452d6016c642f308"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.label ?? tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SliderField.vue"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbc61787024575e5b537be1a62caff81220d60e1b443b66c92b9791d29311ee3"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.details ?? tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/SliderField.vue"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"82ab22e186e0b2b6bb90966a7441b09147882c6a779d8e4e46bc32a083c38095"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.label ?? tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/StringField.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f90edc64a1624525ce3434686a7ed7c033b56bfe523910193eb3c9bf0fb07ec"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.details ?? tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/forms/settings/StringField.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"c82ad914c16270489e5ce93950732fbb7fe81a7c373f695a9aae249b7d0dd671"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060albumStore.album.preFormattedData.description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"e35e4a9b03ec09bdc77abf0379215bfc6c08aa39da5619db27e63336ff43bb69"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060nsfw_banner_override\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"a012f5b9322863ad81157634870eb18c0f9c78fc5a1000a809508a2bb9e16a9f"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027gallery.nsfw.header\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd1799e919b8ae4da6c876cb05981be949c56d9b2ec416678b89f8a1c51e4b0a"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027gallery.nsfw.description\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd496f9e2ce95eba1cc20873e32a5447385473bcb24d7d258fccdbcbfd4e6f2c"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027gallery.nsfw.consent\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"91d763bc24d92255b1ffdf2f390da83872a48a8531a11b7bc9f24bc5e04a3481"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.photo.preformatted.description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/albumModule/thumbs/PhotoThumb.vue"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfe5ad7b47dd10d7f257afa256a4a83142fb594cf1bf3cb8aa21aba6b59d9de3"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.album.description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/flowModule/AlbumCard.vue"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d2098d9da400766488d8209875661f985a817f08c989be5c618d901863c6ae2"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060photoStore.photo.preformatted.description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/gallery/photoModule/Overlay.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"f752ff06f7b78ecc58af265a3cabc0036ad29a36d8e86deb6c3cde589d429b05"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.album.prefix.slice(0, -2)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/FixTreeLine.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c62ed933c9eb32fc06f4a1040574256b9251609a5a94292a46ccfb66e4f8d94"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceBackfillAlbumSizes.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ef4f169371d38cd39c981c81379b9c32dfdb36bad569755fc3702b355a3dec9"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceBulkScanFaces.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6e862499b190abea71dd4a03c224f5fc086fa27f029292ed0147cc3a49f21b3"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceCleaning.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f0ee310b342681659c904005e224c6098ca5c78681b0c448c2d35d79ff0710c"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceDestroyDismissedFaces.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d20d19b5d27fd636d3a06910afc2033a3c2fbc563b503bac4696d784bee28f4"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFilesize.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f7a735a2ff7343292f95a701c2bb5facf54cf6b4be5284b020f0db3dcaa9084"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFixJobs.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b072b6dfafdf0dbe321052eb54bf5c014cc7d205624c8c4bb7511619d993fed"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFlushQueue.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ddc5574a4e86469dfafb90a27087d2dec55a7a2192a415d9c6510a1bfd48301"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFulfillOrders.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f23c0fa3a268afc520d7b776d73566baacae049c3796dadfb0ba8ff3f5ef133"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceFulfillPrecompute.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"83cb85244d5f82bd3094c2d5f44775518f503ecb85d695e0af06c461963af48c"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceGenSizevariants.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0399b84e3aa7e879fb6586cb741f31c1be9099bcbf8293cc39ea465c73d9d6b"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceMissingPalettes.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbe0a093b0c8a654ee0f457151f23015960197cedbbcb6db864863bd9f8c032e"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceOldOrders.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"68d063184ef47a355fcc3d74f76b62a8d6487afcc00a358d721de07c8561e5a8"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenancePurgeOrphanFaceEmbeddings.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9eec3e6589e234f24c8bb470089a562ebb7e2e59e503c2e60e627c024a20070"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceResetFaceScanStatus.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"91b3c2f737466f520ba66690012d46d3803723741cf16916b17315ce87816050"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/maintenance/MaintenanceSyncFaceEmbeddings.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b7ca11b89444d97f099f55d2b1061907c4802e1988345ff1dbcb9119a91d7ec"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060supporter\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/AboutLychee.vue"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f4bba51017ebd912f3a063c551aa8d5b2be21e94f6766694c28e007692f07e8"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027dialogs.session_expired.message\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/modals/SessionExpiredReload.vue"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8779f83846de850303ca9b5dff902c4395cff042d4295304dfc7b0bf96478a9"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027renamer.regex_help\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/renamer/RenamerRuleModal.vue"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"8abad5181eff95eed084d352e2fc9cd619ff78760c6d93a710fed515b9c5160f"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.system.nsfw_album_explanation\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"36a78107368fd87f3f5a8a6c5b26e6c15df93babca6f3d38671c62ff23baa8fd"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.lychee_se.header\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"f54f7e0dbd46e60dfe208949faa8b21f4430e5dc69ac181b90f24da83a464b98"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027dialogs.register.expired_license\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fbae6ff102aba6552e4edf7ba743f19342dad0addf03f6fcff12aba22a79b1a"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.lychee_se.call4action\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/settings/General.vue"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e74de42039ba7769a522bd5baba1136c2445c16e5f2478a4e285c7ed6463c8d"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027webshop.disclaimer.message\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/Disclaimer.vue"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb4ee34d2e49890950251825b37d865ddf9a725fb939506b66ff912ddc8cd81d"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf(trans(\u0027webshop.infoSection.loggedInWithEmail\u0027), strip(userStore.user?.username), strip(userStore.user.email))\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/InfoSection.vue"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b0f009b8d5b690f748d9aa0acd5e1f34e6407265f2ea6a7bc3db9cacc2ae0af"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf(trans(\u0027webshop.infoSection.loggedInWithoutEmail\u0027), strip(userStore.user?.username))\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/InfoSection.vue"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"988fc8db76da06c0cbecf5929280998a91a8189501a21934d5d790cd2c089adf"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf(trans(\u0027webshop.infoSection.consentAgreement\u0027), options.privacy_url, options.terms_url)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/InfoSection.vue"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"8217c16e7443b055864bdcc6de2589c1b3af206b5c5065359d7e416be9c9b39d"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf(\n\t\t\t\t\t\ttrans(\u0027webshop.paymentForm.pciCompliant\u0027),\n\t\t\t\t\t\t\u0027\u003Ca href=\\\u0027https://www.pcisecuritystandards.org/\\\u0027 class=\\\u0027hover:text-primary-400 text-muted-color-emphasis\\\u0027\u003EPCI-DSS\u003C/a\u003E\u0027,\n\t\t\t\t\t\tselectedProvider,\n\t\t\t\t\t)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/components/webshop/PaymentForm.vue"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"512784ca089359ca4661f803593c0f47e0fc1172d289d127ac673475f4f55162"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027changelogs.description\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/ChangeLogs.vue"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"1686b3b67d477c31c3e56e2fba1f425609502031efad34ce4490bf0383492c3a"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060changeLog.changes\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/ChangeLogs.vue"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"c490858f79d532af8e388102513becf37c9da0775e346a4632fe1c068dc69189"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060lycheeError\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Error.vue"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7071cdc6dd054471b4bbf41c14c52c0712f8e248c7bd7adebdedd985a068492"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027fix-tree.intro\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/FixTree.vue"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"55935fb46ff610a0ae744d142a1592a00a541e8fa6ebfcb11aae307547da71d8"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027fix-tree.help.hover\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/FixTree.vue"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"dac52aa61410c3f01c4159e7e3cbccba39880c38c9768226a62211ac85cef021"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf($t(\u0027fix-tree.help.convenience\u0027), $t(\u0027fix-tree.help.left\u0027), $t(\u0027fix-tree.help.right\u0027))\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/FixTree.vue"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1e183679433eb24f9a446be868dbe760113388d1ee59d7756fae093cf675344"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf($t(\u0027fix-tree.help.left-right-warn\u0027), $t(\u0027fix-tree.help.left\u0027), $t(\u0027fix-tree.help.right\u0027))\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/FixTree.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5e5168f5d7bb207342ce236c477ca1976e47df6d28e1b5f5001c6ff14da55be"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf(\n\t\t\t\t\t\t\t$t(\u0027fix-tree.help.parent-marked\u0027),\n\t\t\t\t\t\t\t$t(\u0027fix-tree.help.left\u0027),\n\t\t\t\t\t\t\t$t(\u0027fix-tree.help.right\u0027),\n\t\t\t\t\t\t\t$t(\u0027fix-tree.help.left\u0027),\n\t\t\t\t\t\t\t$t(\u0027fix-tree.help.right\u0027),\n\t\t\t\t\t\t)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/FixTree.vue"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b8064fb09709a88cc12fc156024bfd8c49cf18a31d853ae6223460ce8f625ee"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027statistics.preview_text\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/Statistics.vue"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"bff0f8e764208d2872d062f612c20a09557d7f06f762e633c6e4b74669a6f3b0"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027tags.description\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/TagsManagement.vue"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"802285ba97e316eec9e16bdc8355a0b738006261e2b6c8e3f03c6fab02fc552c"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027admin-dashboard.nsfw_config.matrix_explanation\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"39b5cff5ee02b6660288b1c0084ff35d8141d8f766a8fb47e3915aa1ada23d3b"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027admin-dashboard.nsfw_config.actions_explanation\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":119}}}],"partialFingerprints":{"codehealthFindingId/v1":"fba6c26274227500b06ad4d4bff0f89dd715b924e7848e174dbb4b61b8c86c8f"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027admin-dashboard.nsfw_config.sensitive_explanation\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1cee29ffb54ab3e581a73cb3b89f2da6d634ea71f6249f921c4afd926687b2d"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027admin-dashboard.nsfw_config.hide_on_scan_explanation\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfee6282277c967aa537d712da4db21aab24067db292374c0b95741a61af61af"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027admin-dashboard.nsfw_config.hide_on_scan_warning\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"3536f7b5180eb903221dfc3d7e36cbd60d735b73e97a945358b1c45d5a9d2515"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.small_screen\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Purchasables.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"7de68919c0eaf3a91af9916d578203f581c1f0b45c17520339b305623d5b37dc"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.small_screen\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Settings.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f6c587a763df7fac1b711615327f9abc1bd919c96836d4dff71c95913ef2e48"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tCatDesc({ key: config.cat, description: config.description })\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/Settings.vue"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c2bd079388773d36123611014167237438081e1bb172f305b47e13a8159125d"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.small_screen\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/shop/PrintPixelSizesAdmin.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"9599b88663fa45f9ec21f941fb3de1b7b8f64cf863a51dfa978bbb9793197543"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.small_screen\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/OrderList.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d677f67e2836c5266133448e5bca003c9e0f781b65b6fc327c9f953eaff56e8"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.small_screen\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/webshop/PurchasablesList.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ee5efd2443ca4ba0110cfb5b129f89805017d7a05ba48feecc9b5cd3d9b1758"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027statistics.metrics.preview_text\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/LiveMetrics.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f5a8d27c8f0702a4acc69430cc58257080b9bc972229514ec25f5df1dce3e3b"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060printSingular(item)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/LiveMetrics.vue"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"149b77121f5de3f0b919608ccf18582a944b9dc528211d36ab2c9e3ca114aa2c"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060printPlural(item)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/LiveMetrics.vue"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e50bf4ed6172adedd36542d559b8c72ef5b1987092bdb59ba97237038a31b6b"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060photoStore.photo!.preformatted.description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoDetails.vue"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f9bfac59e67a57e2db57077d51a22b9b185e95f7cd9c5a7b0578b7af2293b3c"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf($t(\u0027gallery.photo.edit.set_taken_at_info\u0027), \u0027\u003Cspan class=\\\u0027text-warning-600\\\u0027\u003E*\u003C/span\u003E\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/drawers/PhotoEdit.vue"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"b393c9855a5d3af62f561210ab1f9048433f8bb5f42514f78a36caa984c8ac7e"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027people.face_recognition_warning.example_body\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/faceRecog/FaceRecognitionWarning.vue"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"0077dfb36cb294e23afaf4e49df5fe30e7778f00bdec1d0f09aeb68231375b9e"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027people.face_recognition_warning.no_liability\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/faceRecog/FaceRecognitionWarning.vue"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8a62acfabb9bb95d759cc8ef8b4ffa23809ef84acfd20030656e61bc259af72"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060footerData.footer_additional_text\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/footers/GalleryFooter.vue"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2f45b29ce1dcb995496ffa648fbcabc117d8de8fb8436bd466a8240a067fc72"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.footerData.footer_additional_text\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/footers/LandingFooter.vue"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f0fbc50591bba7a4d22441104d96c962037a54d27f211a8ab2770bd25768550"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027dialogs.visibility.upload_expl\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumVisibility.vue"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"46ca43da1d19ad431d8708024ab83c281f180c0231e1a4a1298c24a33a4dcd1a"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027dialogs.visibility.password_prop_not_compatible\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/AlbumVisibility.vue"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"feae33b21f6e4fdb2ddf08065e8a024c9ce73d02ca4dc653da7e3b25e40d9881"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027sharing.propagate_help\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/ConfirmSharingDialog.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"80011fbb162dad49ac5a83b35f52ec98f85a46c702719b3e16194700844459dd"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027sharing.propagate_default\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/ConfirmSharingDialog.vue"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"345afee45a6805f84c1b72c7de619bacb63dfcc0a2c298dd4414fb7e32bdea5e"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027sharing.propagate_overwrite\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/ConfirmSharingDialog.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7b54f8f11432d0844b2dbc447c2c9cf843c3ba47012e7a1e413ca680e0fe675"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060trans(\u0022dialogs.embed_code.preview_failed\u0022)\u0060 is text this program did not author, and it is written into the text of an element through \u0060innerHTML\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/album/EmbedCodeDialog.vue"},"region":{"startLine":406}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ec6930e28b67db808e898f4b5c064ae15f9229b380f37efe3de0fb9e119bf49"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027profile.login.password_strength_info\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/profile/SetLogin.vue"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"939b7b4aad02f182e690a400634a6e133dbeeeb5e524e85f7a73316ec62f68e6"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.label ?? tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/BoolField.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"5323e9f09bf84ea81082cb4d0eaaaeaf1580c404216ee08bb7d0102be3d74767"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.details ?? tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/BoolField.vue"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"6290fd8d730a7f5fd19435960802b1de7a2a98c54385b839e58578dcf6545c6d"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/ColorField.vue"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"682d3a4619d396b574b3fdbd9ad8fa0cc9ddada7d5ac714ce3b317af785c5aef"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/NumberField.vue"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"d87e8fbc5530757efaa312930fee3302ada9f56b7f2b47c5112cd7619108ef51"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/OldField.vue"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe5e6603479f63ddc1baaa48cf16e940f51360670dd39d19d428c3a903065cb8"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/PasswordField.vue"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6de144abf86030cf37d338e58e0fa3248d94b32722677551afdbfb6337e5604"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/PasswordField.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a4d9e316ab327d3b593c34bcb26154b0cf6b9cccd633193fc1bcf923ddd98d1"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.label ?? tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/SelectField.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"8997c24500f22be2fc328edecec8caa7888f40ce9a9f8314b6d8078db670bf38"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.label ?? tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/SelectLang.vue"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"4278ab01bf591cfd645cb7ddf0ade9d5558cd8356bffe1a237cb702f14a2fd8d"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.label ?? tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/SelectOptionsField.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"95b04017ac79a14cb55e72d16b258e0462813c4245a7a234b4f97763f22fbcbf"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.details ?? tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/SelectOptionsField.vue"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"fee8bc65f7bef14df7269c4d25eeceb6431c3222885e36f54737bc6fb35f0e07"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.label ?? tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/SliderField.vue"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ab01a9c4e39dd55dbd771824ae1a214b96c864095bfbd89deeb22db59f19416"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.details ?? tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/SliderField.vue"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"8763a2e1c5678ca1dc76e4a25b199d958d386b12fd664899a1b640cb5078b638"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tDoc(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/StringField.vue"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ff50cc0ffe8e11ce8643bf147d883bbd3eb591d466fee88c8212a1565f9772c"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tDetails(props.config)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/settings/StringField.vue"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"d67a11d9bbd7e663dc31030e5b2243c499d4c83bb3e5d47a351f907997c7001d"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060albumStore.album.preFormattedData.description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/AlbumHero.vue"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f3660837141f445d1c699130e1bb63b81408b33ada856e9f0b63a9430af104d"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060nsfw_banner_override\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"099f44aa7763bb498bd16ed6e84524b1f9f73de5348fa67c6476ac4d7f74d8b5"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027gallery.nsfw.header\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ede5cb8d72a11436c49cef97fc52a1d04943beb742a30887a3a99db841d621f"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027gallery.nsfw.description\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6c7571d66c805e323aa9e9d978a78a7db1f8d5fb08f03e97e75a29598da6ee3"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027gallery.nsfw.consent\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/SensitiveWarning.vue"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf0191df449d13b17572b1f3e5797711ddd0c175a1f2081f08b4d3f6a63434b0"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.photo.preformatted.description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/Virtualized/PhotoThumbVirtual.vue"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"d557225f43e8929caa2068cbfd04d0ccb8aa8c6c49f218981364cf4390ebc50c"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.photo.preformatted.description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/albumModule/thumbs/PhotoThumb.vue"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2eb0bc6a4343708b43999ca710b78286bb552b84f33247b042ce904625e9cd9"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.album.description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/AlbumCard.vue"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"78874ef6c58d2dd2bb0dde636b5d3f7ee72e607923ca207de7563f877366682a"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060props.album.description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/flowModule/AlbumCardV3.vue"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"c07f9120e199beaaf76d23656ca2fc369288a9f3355d35ce8cd2e8f406580585"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060photoStore.photo.preformatted.description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/gallery/photoModule/Overlay.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b2138404378d80194e7072234eb7a6af1527d03c9e1ca37c2a531a25dcb9c94"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceBackfillAlbumSizes.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"92407703b1bbf8467fb879146c4f8b3280d7c884fe4bc1777e5475186515d0dd"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceBulkScanFaces.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"aaca65da19fdb53aa3a46c5cfb078d4ab3c1b9d6eb73cf228db4bd3a334df89d"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceCleaning.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"277e7e9d7a2d07584e5407abf8c4ddb81ce6971dd438ff9a5a6949e0565226ad"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceDestroyDismissedFaces.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"25419907682bec77042eb33d6681e831350dfbe067074c9b9ed50cdbe0624576"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceFilesize.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"b61b576b320dac2c01046405745318e0133bd68ff24677ac8b2b66f6ffed0132"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceFixJobs.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf0dffd3feefa1c81cc692cdc480fcc2d294fee0d9d493ff75db8410268d6bcc"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceFlushQueue.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fff78b37107f89fbc736096642ce5b9df1b1fae7c9def062e718fda6957185f"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceFulfillOrders.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"949b9ac90477e71d7c38058fd1307c48ed6f1d3117d595f58964c3f35ae4a61f"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceFulfillPrecompute.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"d08e58e377c12c016a9da0ace1b19ac4da9f7c7b62b687106c06aeea5feaaaf5"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceGenSizevariants.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"ecb5cb28b7041639fb2313eaa5bfc08b7df092c51583e0529e8bc16acf35def7"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceMissingPalettes.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"b64e9b23fc3af8276884442910c0bd52ad030109a4e17317151bc412fb73a3ca"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceOldOrders.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"596b2b9baca36f4f31869f1f7e0fb506a6e0a0181c3da0c1093cff58e475ae75"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenancePurgeOrphanFaceEmbeddings.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"42ceedf63b775b9424470f842f643bbcc771cdaeb1f759330eff3efcdc5d2d69"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceResetFaceScanStatus.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"84775abaa3b73d2e28164242e1b2f5a564814924d0c496d5cff0235367742a8d"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060description\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/maintenance/MaintenanceSyncFaceEmbeddings.vue"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ae66a7c00319508118764af64bb561c54da2b9a0dc9de555343bf00fe713f80"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060supporter\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/AboutLychee.vue"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba571739be350d18d6dca42c6d7a0b42ecec343c91832021919f5fa1091190ed"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027dialogs.session_expired.message\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/SessionExpiredReload.vue"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"711517b8c32c552b6c980361dd74fa9c1025fc296b7a12b29ce661181f3e0872"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027renamer.regex_help\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/renamer/RenamerRuleModal.vue"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b5536d20aaa6eebd530a065d46920aedfd216a61d1e6f219ad5697b6c31c738"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.system.nsfw_album_explanation\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ac0478d2f14c419038dd973020aedcbfa6fd6b6eb6152bfd396729ae9bda03e"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.lychee_se.header\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"35c5250097e57907252aedb31a0adc5e5719771cb4ea35fef6254d526c4916c5"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027dialogs.register.expired_license\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ae23ed395f9b0eb8cf8bc32dfe57dd1277f9588f5040eca3442210359c04003"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.lychee_se.call4action\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/settings/General.vue"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f84c90b147dd8cd367f7b05d58cf186dd170cf8682233490138962808585294"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027webshop.disclaimer.message\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/Disclaimer.vue"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"800a9dce35a119fa45d31226f1cd2b0b08cce4907b5e9fbbf73a527da478a1c9"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf(trans(\u0027webshop.infoSection.loggedInWithEmail\u0027), strip(userStore.user?.username), strip(userStore.user.email))\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/InfoSection.vue"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c138f81be0cf8c6f5bce7bc15c651be36dd7c4d26cc77f05e641b9716b2890a"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf(trans(\u0027webshop.infoSection.loggedInWithoutEmail\u0027), strip(userStore.user?.username))\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/InfoSection.vue"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac8031cbde63d6030cc1674071ee935f3ff87ccbef5743fbedbfc95f1d359b5f"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf(trans(\u0027webshop.infoSection.consentAgreement\u0027), options.privacy_url, options.terms_url)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/InfoSection.vue"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"683734b424af2c9a9b9782c1627cb33d3ea4c60425fd199755011d81ea3fed25"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf(\n\t\t\t\t\t\ttrans(\u0027webshop.paymentForm.pciCompliant\u0027),\n\t\t\t\t\t\t\u0027\u003Ca href=\\\u0027https://www.pcisecuritystandards.org/\\\u0027 class=\\\u0027hover:text-primary text-highlighted\\\u0027\u003EPCI-DSS\u003C/a\u003E\u0027,\n\t\t\t\t\t\tselectedProvider,\n\t\t\t\t\t)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/webshop/PaymentForm.vue"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2b180b4f2c6dc56df5606e0b5f259c1e1246dbe9794a60d4668123792ab4918"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060welcomeText\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/AdminSetupPage.vue"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d343a559d2f0e674f2c0b64210ce9cc7892ee136a734d5e6eb32d1c82213640"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027profile.login.password_strength_info\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/AdminSetupPage.vue"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"9187e31da800a09e504e994587c3bfefe4e7b08456eaeb2d2abb6f0ee9d8d68f"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027changelogs.description\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/ChangeLogs.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"798087256781c95416471134a8282832048ffd44d6891d09fdc6910840359c31"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060changeLog.changes\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/ChangeLogs.vue"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"20891f9ac201e34d1f148aa9fdda170de5806f698773ea7fbe54de065ca176be"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060lycheeError\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Error.vue"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"6adf28c6386a4ff086a50e765384dad0c94e4e83438c9c83ab7b0b288a3352fe"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027fix-tree.intro\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/FixTree.vue"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f2786aabc1487dca1e1de2260f0bc2fd39faf898110c4f2d80f618d2acef915"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf($t(\u0027fix-tree.help.convenience\u0027), $t(\u0027fix-tree.help.left\u0027), $t(\u0027fix-tree.help.right\u0027))\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/FixTree.vue"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"893a5524ee05c0fd49798595a5882ef9447947ac18155d7c77a258032e174517"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf($t(\u0027fix-tree.help.left-right-warn\u0027), $t(\u0027fix-tree.help.left\u0027), $t(\u0027fix-tree.help.right\u0027))\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/FixTree.vue"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"549539e6777e3b6492149d1194b3ab27650d8a48c428839a02fd5ea285605335"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060sprintf(\n\t\t\t\t\t\t\t$t(\u0027fix-tree.help.parent-marked\u0027),\n\t\t\t\t\t\t\t$t(\u0027fix-tree.help.left\u0027),\n\t\t\t\t\t\t\t$t(\u0027fix-tree.help.right\u0027),\n\t\t\t\t\t\t\t$t(\u0027fix-tree.help.left\u0027),\n\t\t\t\t\t\t\t$t(\u0027fix-tree.help.right\u0027),\n\t\t\t\t\t\t)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/FixTree.vue"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ce293427252926918d1876fdaf681ff94cba67b7637cce6f5669c18a36c83f4"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060albums!.prefix[index].slice(0, -2)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/FixTree.vue"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"34c0866a99cec78a6742391adeaba972c07e0923c04bb65dca3472adf4c1a452"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027insights.preview_text\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/Insights.vue"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a0db601491b31e2bbb93a3845cc1be96dd988f1e32f07977c9d5e6315cda264"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027tags.description\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/TagsManagement.vue"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a8d0d5a9e916b0515182c34dbba270c2d73f56d47dc726edade6162e05bed5e"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027admin-dashboard.nsfw_config.matrix_explanation\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/NsfwConfig.vue"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"8170cbce820853a0b1511e4eaa0e1f6f06caedf220edbacc89dd90205b925327"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027admin-dashboard.nsfw_config.actions_explanation\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/NsfwConfig.vue"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c7dca14593720f3d53a0b321d3f670f144d8f2f83e9bdc04cf2ca5dbd884c22"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027admin-dashboard.nsfw_config.sensitive_explanation\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/NsfwConfig.vue"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc141c247023ab18276e54bc939283bcdb2f5322dfe57eda80ebce5335aff6fe"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027admin-dashboard.nsfw_config.hide_on_scan_explanation\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/NsfwConfig.vue"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"c02e7a2d1827a99b669a6b47183888c05b09008c9fa833467060629da2876ab5"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027admin-dashboard.nsfw_config.hide_on_scan_warning\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/NsfwConfig.vue"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"fee0783aea0f50e3a33bc227986a13d02c87e0b61a5b9b002bd91a7bfad8c6ff"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.small_screen\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/Settings.vue"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"3df08bbf7a1464160672937c00b6e9abf89f41b8b0ddb4fe81097cabec5bbce3"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060tCatDesc({ key: config.cat, description: config.description })\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/Settings.vue"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"89b9f16ea8bd03a1b3b8d7105360b4f5a24443600a10f3d74633ff43670ddb17"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060data.about_text\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/landing/LandingPortfolio.vue"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"585bd187ba2d08c1895ba000878e13d40027b327ee7e3eac98dec74fb4c67776"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060data.about_text\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/landing/LandingStudio.vue"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6546d56b0f3cbf258084a69ef4c9788f26dad31b4d501f5fb6dd83c1abf8b32"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.small_screen\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/webshop/OrderList.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"b299811495e15e651fe76c3054ac644d374e3ad1caf25de365a9e09eb7927641"}},{"ruleId":"X24","level":"warning","message":{"text":"Untrusted text written into markup unescaped: \u0060$t(\u0027settings.small_screen\u0027)\u0060 is text this program did not author, and it is written into the text of an element through Vue\u0027s \u0060v-html\u0060 with nothing encoding it for that place. Whoever controls the value controls the markup: it can close the element or attribute it sits in and open a script of its own. Encode it for HTML at this site, render it through the framework\u0027s escaping output, or sanitise it if it must stay markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/webshop/PurchasablesList.vue"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0f9ff03af7036d7384d97b94a581eb25747b2a442ffab389122749d85d7995d"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (\\Exception)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Insights/Helpers/LocalCaptureTime.php"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bcc351dea4b95b27d2506c6f8b3e61cb13be8e7a8d9779a40f95af068eb7a30"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (\\Throwable)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/BaseArchive.php"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"15164b866a1d0891a18778b30f3d4065e3cff7c18bb6e87ecdf0ccd481ba6120"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (\\Throwable)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/BaseArchive.php"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"6001806d360430703264b19b250b0d618b223058de7006bc615ff30ef9b0cb92"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (\\Throwable)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Exceptions/Handler.php"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"3fa132aff821f6f04a3a5414196e3f9538512a69b8ebdfa3c60e9a2dfcbb60ea"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (\\Throwable)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Exceptions/Handlers/NoEncryptionKey.php"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c82151e98da1331d349a8821f88916b0ce0518fceed934008983e612b52e6d5"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (\\Throwable)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Exceptions/Handlers/MigrationHandler.php"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3bbe4f567cfb223d5ce0df0b952c1ba2a7a91a32fc8a94e131216e14962e196"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (\\Throwable)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Exceptions/Handlers/InstallationHandler.php"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"40d043e951d295a4afbc46d0c00749c1ecd824325303ce41890729bf7615625b"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (\\Throwable)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Exceptions/Handlers/AdminSetterHandler.php"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"63c5fba698e33a80b3a88f88536c5744372997bb41e3d64f5abfb33b833e7a8f"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (\\Throwable)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Exceptions/Handlers/AccessDBDenied.php"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"58bf0cbe572ac898f9ab87b17615b31bd14857119dadae62471dd6f5b4327eb0"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (\\Throwable)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Metadata/Json/ExternalRequestFunctions.php"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3806082698d865831926c372dde9ca547cdffc7f06b151e5b5eb73b94349046"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (\\Throwable)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Repositories/ConfigManager.php"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"0255a8fc23c77bc1d821ee832d160a8f043c9fc5e9af52bdb74ababc969caf6b"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/2025_05_27_081037_drop_legacy_id.php"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ce1c7a967870cbf2e03625bd9440b7b9a6c7895e9376db0841cacc871caf974"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (\\Exception)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"database/migrations/2023_08_07_182802_add_config_ffmpeg_path.php"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa3c50d5fb1e9271f100e76c28ef185f14e75230d716a4d780797c44d71a1f15"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useGlobalRights.ts"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"d46eb4dfcf07d4a2ca3f0de347095646c622bec2d5ffcf3d87d00fdb9d46adfd"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/useGalleryLock.ts"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee6e31d3a70533793770fea1bf2d6f47d5fc45f63e42b875eed8ae09560caac0"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/composables/modals/useAdvisoryModal.ts"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"f52c651e1d7c0774552a8afd6ced7f43ada31da018d181b1902e45fdf6ef5ded"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/config/axios-config.ts"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c8480898614ceebc4b604a621cf0d3025e73fadabde0ba10c6cb0b758352c01"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/menus/LeftMenu.vue"},"region":{"startLine":179}}}],"partialFingerprints":{"codehealthFindingId/v1":"73b247e7d6c741e301bdabd80c9dec88898e14f531ced7a0626861ec2d09f787"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/menus/LeftMenu.vue"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"17f0a2943fcc855641a41bdc31af5d425e8271eeb3d071a4a1db5c344e369d43"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/NsfwConfig.vue"},"region":{"startLine":359}}}],"partialFingerprints":{"codehealthFindingId/v1":"0caf2ba3c0ed1f7164d61a65b4db98a03e9e98f0d8d9d5da41c1e1ab3cd342bd"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/AdminDashboard.vue"},"region":{"startLine":270}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b14f7062b22a3248fbdbc2b4a13283a84e86cc6be53c7ca4250b85573387f22"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/admin/AdminDashboard.vue"},"region":{"startLine":280}}}],"partialFingerprints":{"codehealthFindingId/v1":"d00b9b36f603afeda592cbb723997f294973b766fd9b9af78e3066aba16083ad"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/People.vue"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"eccce66b61a8b4b85438286891a26b45e1916b72e6b087e0b80ffab64cf5a903"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":408}}}],"partialFingerprints":{"codehealthFindingId/v1":"c74cc135228703d462e5c8e437840a7f9286761dc8f102ea1608ce1ad0bb5070"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":476}}}],"partialFingerprints":{"codehealthFindingId/v1":"753ced6de2a39d66348dcdae9c5555b0e02425aeca2e03271d33ba18a2a73d63"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":494}}}],"partialFingerprints":{"codehealthFindingId/v1":"606a957d1d9940e54dadfb2d09a175f4ea7dc1b14f6f78794aa7d7e8059b1641"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":561}}}],"partialFingerprints":{"codehealthFindingId/v1":"1debd24300e8673b36ea65ea15de9aed3b5d0b31b38df926ebb46c192c891b5c"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/face-recog/FaceClusters.vue"},"region":{"startLine":596}}}],"partialFingerprints":{"codehealthFindingId/v1":"fed19f14f6ce0d441476913ba9f0a40a60406862c06c5556412cccf8de881257"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Frame.vue"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"6284e227f0404d6a7dcda73cea106fe20e789f00171ab8365a795c59f4f373a0"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v7/views/gallery-panels/Frame.vue"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"e58d632dacb6786a57beb880aaf4efbcc373b25cb6dad9793fe848fc05acbe07"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/forms/auth/LoginForm.vue"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"c66bc28c7ee426bdb1fc90328b46e5313ddbd501a8882de90a5c47196f8b89e1"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/WebauthnModal.vue"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"45a3b607ee599f1f335ab8136254063aa2d2f1fcb59c0bef2f10e6c15e66b005"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/components/modals/SpotlightSearch.vue"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6aaa2636242a5012fe23d67b407dabb54a2f9d127fc2b456be74990cfcdd633"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useQuickNamingSession.ts"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae3c53afe60774aed1acc2d3061b11dd9f9ab30661669f5c27a085004cbfd179"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useQuickNamingSession.ts"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"95ce6d60ae988fef6b3ea14cf2b65ae821590e9fe17ca146915ed6d1ea766693"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useQuickNamingSession.ts"},"region":{"startLine":343}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e0b0efd0ce9819e2059a0ed050467210601ad74269adee385be327e66a35617"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useDarkMode.ts"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"0260140dcfad5b6892985a0cb2b375f6427978d9a3455b255611e0a2f7042185"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/useDarkMode.ts"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"b3e308ac5969777cd8eb0d2b413c66b398bebcffa90087ad0070368953e97d6c"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/composables/album/albumDateScrubberState.ts"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"aac437dd9d83d1fda9672a9e8aff47188fae8a4a2c98f4109019a12dbd66fa4b"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/menus/LeftMenu.vue"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba8ac6b0b5a046f8d0adab0f90ebecc64d47cea907e5304eb63fea2c22a41bf4"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/menus/LeftMenu.vue"},"region":{"startLine":205}}}],"partialFingerprints":{"codehealthFindingId/v1":"faf1c45c7f13811266eb18fa38cbfe37ba023aec18908c2d29c85d1838d8a0d8"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/NsfwConfig.vue"},"region":{"startLine":318}}}],"partialFingerprints":{"codehealthFindingId/v1":"488589a4b6cec5c1ce922bdfa21268a83d79d88388eaf2ea18bc9a609a6b7bb9"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/AdminDashboard.vue"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"966c4dcb5cd154aecc9d728da99422d2ac453a487b9c11a297af21cbfd956983"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/admin/AdminDashboard.vue"},"region":{"startLine":230}}}],"partialFingerprints":{"codehealthFindingId/v1":"e844f312b688eab05b9a1951f6ad689f8cacfa97915f889f2c6b820658262a0c"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/People.vue"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"df78b55be6e8d4bc3f2665a565e836a1ea5ef587981060132c82068ffb637042"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/FaceClusters.vue"},"region":{"startLine":603}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f4f04d6e8753dc15eb91f0083e1ff727069300eb3f160041c525815ba82b3bd"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/FaceClusters.vue"},"region":{"startLine":663}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c722161806e2388b6fb54ef992d52f74fd7c369abcdafdabd7dc731d44fbc16"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/FaceClusters.vue"},"region":{"startLine":735}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f9d90eac6c920f91d9743ed97c80ff19a9d5c3cebfcf2aa37a57ea062f581a2"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/FaceClusters.vue"},"region":{"startLine":823}}}],"partialFingerprints":{"codehealthFindingId/v1":"1867dfc3fbd76c6326e95970ece6815eabde58b0aca43fd8d20cc06b5113174b"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/face-recog/FaceClusters.vue"},"region":{"startLine":836}}}],"partialFingerprints":{"codehealthFindingId/v1":"688a43fc860e40e5925ac7183840019a3a8d80713100234a7fa05f76465e3bdb"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): \u0060.catch(() =\u003E {})\u0060 handles the rejection by doing nothing \u2014 the failure is discarded with no log and no rethrow, and the chain carries on as if the work succeeded. Log it through whatever this codebase already uses to report problems, hand it to a caller that can (\u0060next(error)\u0060, a returned rejection), or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Map.vue"},"region":{"startLine":365}}}],"partialFingerprints":{"codehealthFindingId/v1":"2da893e0a7c31ed1b354137ba29ea5ee3b44847d094b473c05483a7553e5d189"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Frame.vue"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf9ce9704f692a48730d55fd9d5b8215a00fe2c9706b45cf425ca964c0970fdf"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/v8/views/gallery-panels/Frame.vue"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cac2321c79aa26e9e2eddaad85945f696ff017278f7f7b4b4af07a604334b86"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 48 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/Pipes/Standalone/AutoScanNsfwOnUpload.php"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"e630fefc98e45c7c48e86adbb268545c1a874537eaa420c22e7b7aa877959d6b"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 48 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Actions/Photo/Pipes/Standalone/AutoScanFacesOnUpload.php"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"3610cd883d00687dcffe1090215ed4538cdb7aa07aa53303ee08504cfb712fa0"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 66 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/ScanFaces.php"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"531d761c235262de4f64eb2d107d7303380e3a6e1eef899150ec9e2c733877af"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 64 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RescanFailedFaces.php"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1ed2c13ca2c526b5dc414436ca1986bd09760d9c36d998ede4dba6a836f2c2b"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 79 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RescanFailedFaces.php"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac89c6c5fb098a12df2f95e8349ac17d28b72659c809a0cf62a154850f5c00c3"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 65 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeBuckets.php"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce67a44f1c2147c9c727cb5a1bc4fe24bb1d902cd117109ac41c3a143909f1e0"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 75 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumStats.php"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"f734b31208bee6eb4c9174f1de0725655b822c1c69fc9b1fc3380f0331547724"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 91 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumStats.php"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fd8b868b3ea4fbc5369c385a72abbceda4dab2caf8f729e6d62b825112e2cfe"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 147 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumStats.php"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"7025e223c58b54d0f62412661f484ce7d51cf5fb3f3f55c462f03ebea2a99f54"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 163 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumStats.php"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"e87f7b90d0f4869943a5c7310d90aa941cda5a90cdea12c6818c9f63f577d3ec"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 75 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumSizes.php"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"8634dcf615cfed000b326bc8915c2900d403195ae8cb7ccc9c3042d1d03bbf64"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 91 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumSizes.php"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1a762093e751b5198e6662904af1b53fe34d96e9845eb2df8bf130a4f3d4bc2"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 146 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumSizes.php"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"7453afd880c5cc21b5c4ef45fdff91699586522da7aaf0c2b7e46fd64ffd0a2d"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 162 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Console/Commands/RecomputeAlbumSizes.php"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f5a5e9c5f1e0759388e8f7013512ae83fa6557d910ccc1dafdc2bd947483195"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 89 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Admin/Maintenance/SyncFaceEmbeddings.php"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7b5c2aa332db213654b659f427fe366eb2688dae64008018b712d10a90bd2e0"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 97 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Admin/Maintenance/SyncFaceEmbeddings.php"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"a82ca97fc8f079e94fceaac883ca12b8d68860a00acc0b7affdeef486f4369eb"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 88 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/Admin/Maintenance/PurgeOrphanFaceEmbeddings.php"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"da23410bd3b7dfac3b72653b087e310cb743052b9a6afa825a6fb6bad0be8e3e"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 35 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/AiVision/NsfwDetectionController.php"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"edb407c2d6d1f8360f9afa5e234edb79c7ab9831aa2afdb0376d4dbe590f511c"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 43 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Http/Controllers/AiVision/NsfwDetectionController.php"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"78856f3aa6fcc9973a87c3aae001b7ee1252a8f1ff88cd2a1062422697ee6a5b"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060error\u0060 at line 67 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Eerror(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::error(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputePersonStatsJob.php"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"3fe543b8aa1435c58837346bf9e4af71b11d4c9e8844b62c7d0c7b2e06d84253"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060error\u0060 at line 70 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Eerror(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::error(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputePersonStatsJob.php"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"91b60f8336f709be5d2bac1c3ae20485c87ddafa49216673696364ad3eee0e0b"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 92 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputeAlbumUserThumbsJob.php"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"610318e458641c1c2fea7977b7fcd29f2acb0e5cddd8a984bbf967f8a9bb1b1a"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 98 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputeAlbumStatsJob.php"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"7cf91e6ce7322885cff7d4609ce2b0df372237b8fd778a4d86c2ca1ebffc6f50"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060critical\u0060 at line 103 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ecritical(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::critical(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputeAlbumStatsJob.php"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"b79d6ce70c274eb6facf1f05e1f67ed1280d02e68c5d39ec426a4800b36df9eb"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 112 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputeAlbumStatsJob.php"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"93c44ccffb3ea431eb7263bdf4287ca8787340dc457bf04584510d004af79368"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 145 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Edebug(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::debug(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputeAlbumStatsJob.php"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"3146ff8e62ceb83aa102b46e61c51ec537034a5246d84622bac59c4c8dc091be"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 84 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputeAlbumSizeJob.php"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"14a635179053c9539d021bdc36f717b9db21943fd7c57f890e3e6105d34d53fb"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 90 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputeAlbumSizeJob.php"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"69b15a57d33bad35c6707a7a1a145cf13d1111b2d1dd91a7517cd91a1ee9c4d9"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 112 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Edebug(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::debug(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputeAlbumSizeJob.php"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"f24c5ef247a46d2a7e634a04aec717dea8f5d33902873df822f5f5d4a1eac6c5"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 118 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Edebug(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::debug(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/RecomputeAlbumSizeJob.php"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"17ffac6959a3032a9cefb96ff108f315f29b26f0b9a8ad5a78997daecb258e46"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 77 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/GeodecodeLocationJob.php"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7d6413c48cdb0bc5f93375d78bf5fe413f246ace33d3d4ae8bb9a3e1548f460"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 69 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Edebug(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::debug(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/FileDeleterJob.php"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"be039358ebb69ea4f54e5b613b67fa23a577fa7d9a270b512c03342a8b141007"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 89 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Edebug(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::debug(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/FileDeleterJob.php"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"27857c159bfe6044478b36efc561ee8c3c53c9120744830682c3bb9026f61866"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 87 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/ExtractZip.php"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d7b76724a4fe66621c069681a079ad534043ca10f15d8cfcb0cc4d6e6c1cfaf"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 67 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/ExtractColoursJob.php"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"e180d9a9e518ca5df86bd16e94b84dd4808ab0059cab484ea1c5fff766141062"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 41 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/DispatchNsfwScanJob.php"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"9cdbf320af53634128a9524c76135edb2754e1107f74b05ef718800f33840c28"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 47 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/DispatchNsfwScanJob.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"e65816531735228756687442cd993270a52b91e809b94d975b353318b545db65"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 57 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/DispatchNsfwScanJob.php"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d80412db877c2389a599ee9f0864ea2e905476f787d038e23d00820aa1a5599"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 71 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/DispatchNsfwScanJob.php"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9373020945d8cc21c5be48494104490da43094f265d29c1e986c996e4397159"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 47 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/DispatchFaceScanJob.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"981503cbb255b110487f69308607ff42020e20bcf2066b77ededf3cccf05447c"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 53 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/DispatchFaceScanJob.php"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb838ff0fb420843ea4e9be9fdedeed16bd9595aadd4f751d5b8878af9f051d4"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 63 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/DispatchFaceScanJob.php"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"72d9c95183c40b3c73fd5260400f42424ded64a7f13f50dd6a962fe8551051d1"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 74 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/DispatchFaceScanJob.php"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed285ad2e3d21828ae57cc85f32163aabee0b1aa9b656697de9ef90465b53ca2"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 54 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/ApplyNsfwAlbumSensitivityJob.php"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b18603eaece1b6da81ce09a782e0c52f45bdcfdc6a882761631e97a30018f6a"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 63 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Jobs/ApplyNsfwAlbumSensitivityJob.php"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"0300dd7671c0c3cd726fca7d3d55d913fef828712498a457c5e8399d9a9a7e08"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 60 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Listeners/RecomputeAlbumStatsOnPhotoChange.php"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbcefee12aa1253ac3c91c7229f90591b9c514278bad7952cde25b34869cc91c"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 29 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Listeners/RecomputeAlbumStatsOnAlbumChange.php"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a3c870f00242acd3a7cffc4700ddce7d439667d15d97cde0f6ed4d71465e4f3"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 50 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Listeners/RecomputeAlbumStatsOnAlbumChange.php"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"45295ce07bafd4ed0fcc18fc83d6bec9c1a741638d7fce19842d73e0e93fba33"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 55 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Edebug(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::debug(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Listeners/RecomputeAlbumSizeOnPhotoMutation.php"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"a462c6b0e8cea9d0cbc4267225566c51a44ae066845e2e9e52478c25236ef364"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060debug\u0060 at line 74 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Edebug(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::debug(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Listeners/RecomputeAlbumSizeOnPhotoMutation.php"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"392d588a750a10cdfa1bcbdff79782acee3e91e8f5266d39e3225871210a6c2a"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 38 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Listeners/RecomputeAlbumSizeOnAlbumChange.php"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c56208af86ea6462bada8a076a85bddbd0b41e86e76fd9a08cdd6f9679875b7"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 59 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Listeners/RecomputeAlbumSizeOnAlbumChange.php"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"67a817709937a525d9c79b830fbb9aeabe72f7ec04663c04ab8ccf8fad5103ae"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 154 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/NsfwDetectionService.php"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"6530075af47659ae92373dbcecb2da3b38fee76a861dd96e297541b573ec7dd1"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 47 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/NsfwActionService.php"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"954dfd9aeb8ecaafd986ccc76a12e00a1a90ac3d1eb801fa6e6d8af90225e6e6"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 115 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/NsfwActionService.php"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae49f405379927af7af00ea32760aafca015af69788c2f2f21102a5104b51556"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 123 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/NsfwActionService.php"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"2bfbd095476742f89e3986a8a004fbd69bfdc9983754a98646fef7985230c7d5"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 130 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/NsfwActionService.php"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbd1de18ebcd083ea6681ab8a8fecc2ff861e976f75064b979c36497ff266c30"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 144 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/NsfwActionService.php"},"region":{"startLine":144}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5ac342d2ff1b292bef0c137936bfc7f5505eb300bd34bb8aa61c4918cfb048b"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 151 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/NsfwActionService.php"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e56a68e203da28c23130e08e0ef84eb396c93af566868ac2c6e1fd686215d12"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 175 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/NsfwActionService.php"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"5381553e1496343d818faa2dd22cc1581ce73e28f199ccbf4f9eb75610c00536"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 195 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/NsfwActionService.php"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"913d747ea543a8d6c3e17c3d36ae6c61bab193b61874492f4fb63f852ff61822"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warning\u0060 at line 209 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Ewarning(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::warning(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/NsfwActionService.php"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"6db7a7573820865c03601232e7ec6781ff686350748d456022f40d5788664133"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 216 is handed a double-quoted string with variables interpolated into it as its message, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, and every occurrence reads as a different message. Pass a constant message and the values in the PSR-3 context array instead: \u0060$logger-\u003Einfo(\u0027Order {order_id} moved to {status}\u0027, [\u0027order_id\u0027 =\u003E $orderId, \u0027status\u0027 =\u003E $status])\u0060, which Monolog and every PSR-3 handler keep as fields beside the message (Monolog\u0027s PsrLogMessageProcessor fills the placeholders), or \u0060Log::info(\u0027order moved\u0027, [\u0027order_id\u0027 =\u003E $orderId])\u0060 with Laravel\u0027s facade."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Services/Image/NsfwActionService.php"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"feeb8a863680527cf12fa4ffe135e291770ac99c898a6bd8716e0c750efde586"}},{"ruleId":"X5","level":"note","message":{"text":"PHP static analysis does not check null everywhere: 0/1 of this repository\u0027s PHPStan/Psalm configuration(s) run at a level that checks null \u2014 PHPStan level 8 or above (\u0060max\u0060 included), or Psalm \u0060errorLevel\u0060 3 or below (Psalm\u0027s default, with none stated, is 1). A PHPStan level written neither in the file nor in an include inside the repository is 0, PHPStan\u0027s own default. Below those levels the checker removes \u0060null\u0060 from a union before any rule looks, so \u0060$order-\u003Ecustomer()-\u003Ename()\u0060 on a \u0060?Customer\u0060 passes, and the first null reaching it is an \u0060Error: Call to a member function name() on null\u0060 in production."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"4ee877508ebc333ebff2765634874753d7fd67f71ea749a6c333792a59b461d7"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060convertExceptionToArray\u0060 swallows every exception into \u0060return []\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it propagate. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment in the catch or in the docblock, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Exceptions/Handler.php"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"deea6bbcbc3dd59bbfd40d2cd6bc8a493966a00835d3ab4dd54409ef28f6c7b8"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060get_age_text\u0060 swallows every exception into \u0060return \u0027unknown\u0027\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it propagate. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment in the catch or in the docblock, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"app/Metadata/Json/ExternalRequestFunctions.php"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"7bb6ae168a2b52d924d339b51dd3272a9f6719169791044541fe456e81624e99"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060extractErrorData\u0060 swallows every exception into \u0060return {}\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"resources/js/config/axios-config.ts"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"15232f26c94b5ccfa0112d2bb1d443150b709bdb2fa1fe411f46b25c2bcd9f17"}}],"taxonomies":[{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d","organization":"MITRE","informationUri":"https://cwe.mitre.org/","isComprehensive":false,"shortDescription":{"text":"The MITRE Common Weakness Enumeration (CWE)."},"taxa":[{"id":"CWE-1032","guid":"5f21e517-68aa-a650-9a25-5771ef024637","name":"OWASP Top Ten \u2014 Security Misconfiguration category","shortDescription":{"text":"OWASP Top Ten \u2014 Security Misconfiguration category"},"helpUri":"https://cwe.mitre.org/data/definitions/1032.html"},{"id":"CWE-1059","guid":"a2381a08-60f6-9554-a8b8-f3018cfaaca5","name":"Insufficient Technical Documentation","shortDescription":{"text":"Insufficient Technical Documentation"},"helpUri":"https://cwe.mitre.org/data/definitions/1059.html"},{"id":"CWE-1357","guid":"e4d2e772-757e-0a5c-bd7d-77052949d866","name":"Reliance on Insufficiently Trustworthy Component","shortDescription":{"text":"Reliance on Insufficiently Trustworthy Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1357.html"},{"id":"CWE-1395","guid":"800e09e7-c11a-8654-9fa6-86f398995fed","name":"Dependency on Vulnerable Third-Party Component","shortDescription":{"text":"Dependency on Vulnerable Third-Party Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1395.html"},{"id":"CWE-16","guid":"659db3ea-affc-8453-8add-c1218fbfcb92","name":"Configuration","shortDescription":{"text":"Configuration"},"helpUri":"https://cwe.mitre.org/data/definitions/16.html"},{"id":"CWE-200","guid":"b0ce3b1d-7a29-fe50-8aab-9aba899d2988","name":"Exposure of Sensitive Information to an Unauthorized Actor","shortDescription":{"text":"Exposure of Sensitive Information to an Unauthorized Actor"},"helpUri":"https://cwe.mitre.org/data/definitions/200.html"},{"id":"CWE-250","guid":"52ee12e8-390a-7351-b1e6-388afa694e54","name":"CWE-250","shortDescription":{"text":"CWE-250"},"helpUri":"https://cwe.mitre.org/data/definitions/250.html"},{"id":"CWE-259","guid":"ae9ad959-fbb6-9d5e-892d-3dca66da0b69","name":"Use of Hard-coded Password","shortDescription":{"text":"Use of Hard-coded Password"},"helpUri":"https://cwe.mitre.org/data/definitions/259.html"},{"id":"CWE-276","guid":"4e27da05-61af-1d5c-aeb5-9f56b6ede3e3","name":"Incorrect Default Permissions","shortDescription":{"text":"Incorrect Default Permissions"},"helpUri":"https://cwe.mitre.org/data/definitions/276.html"},{"id":"CWE-290","guid":"379b1e66-a292-7b59-aa1e-a5bb4a6a99e9","name":"Authentication Bypass by Spoofing","shortDescription":{"text":"Authentication Bypass by Spoofing"},"helpUri":"https://cwe.mitre.org/data/definitions/290.html"},{"id":"CWE-319","guid":"7af97476-9f0d-4458-9163-3d2043918a1a","name":"Cleartext Transmission of Sensitive Information","shortDescription":{"text":"Cleartext Transmission of Sensitive Information"},"helpUri":"https://cwe.mitre.org/data/definitions/319.html"},{"id":"CWE-353","guid":"09d7e902-d4ee-f05d-ae6c-0a1554d0c18f","name":"Missing Support for Integrity Check","shortDescription":{"text":"Missing Support for Integrity Check"},"helpUri":"https://cwe.mitre.org/data/definitions/353.html"},{"id":"CWE-494","guid":"b8a65e0d-e459-4a55-a931-fc1136482375","name":"Download of Code Without Integrity Check","shortDescription":{"text":"Download of Code Without Integrity Check"},"helpUri":"https://cwe.mitre.org/data/definitions/494.html"},{"id":"CWE-506","guid":"401d6455-56e3-0552-9a39-f77461673e3f","name":"Embedded Malicious Code","shortDescription":{"text":"Embedded Malicious Code"},"helpUri":"https://cwe.mitre.org/data/definitions/506.html"},{"id":"CWE-732","guid":"1da27e8f-b330-7650-ab63-bd61953eae5d","name":"Incorrect Permission Assignment for Critical Resource","shortDescription":{"text":"Incorrect Permission Assignment for Critical Resource"},"helpUri":"https://cwe.mitre.org/data/definitions/732.html"},{"id":"CWE-77","guid":"332c8ade-6612-9f56-a06b-d8d90b1a8750","name":"Improper Neutralization of Special Elements used in a Command (\u0027Command Injection\u0027)","shortDescription":{"text":"Improper Neutralization of Special Elements used in a Command (\u0027Command Injection\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/77.html"},{"id":"CWE-78","guid":"2e31ceaf-c7ae-2e5e-9661-cfb1362789cf","name":"Improper Neutralization of Special Elements used in an OS Command (\u0027OS Command Injection\u0027)","shortDescription":{"text":"Improper Neutralization of Special Elements used in an OS Command (\u0027OS Command Injection\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/78.html"},{"id":"CWE-79","guid":"fd45580b-e8c4-fc5e-8c2f-aa8fab0b4dbf","name":"Improper Neutralization of Input During Web Page Generation (\u0027Cross-site Scripting\u0027)","shortDescription":{"text":"Improper Neutralization of Input During Web Page Generation (\u0027Cross-site Scripting\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/79.html"},{"id":"CWE-798","guid":"5e8f057d-fee3-995a-a0cb-9fc5b0d174d1","name":"Use of Hard-coded Credentials","shortDescription":{"text":"Use of Hard-coded Credentials"},"helpUri":"https://cwe.mitre.org/data/definitions/798.html"},{"id":"CWE-829","guid":"13c33925-97fb-5a5e-b40c-56d328b8a4d7","name":"Inclusion of Functionality from Untrusted Control Sphere","shortDescription":{"text":"Inclusion of Functionality from Untrusted Control Sphere"},"helpUri":"https://cwe.mitre.org/data/definitions/829.html"},{"id":"CWE-89","guid":"6d08fdad-37eb-c150-bbf0-d7d946863407","name":"Improper Neutralization of Special Elements used in an SQL Command (\u0027SQL Injection\u0027)","shortDescription":{"text":"Improper Neutralization of Special Elements used in an SQL Command (\u0027SQL Injection\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/89.html"},{"id":"CWE-937","guid":"16f316ae-415c-b354-a59b-1f7905f756e9","name":"Using Components with Known Vulnerabilities","shortDescription":{"text":"Using Components with Known Vulnerabilities"},"helpUri":"https://cwe.mitre.org/data/definitions/937.html"},{"id":"CWE-94","guid":"75e7f50c-6c2f-dd52-bf40-bf6c52b861fd","name":"Improper Control of Generation of Code (\u0027Code Injection\u0027)","shortDescription":{"text":"Improper Control of Generation of Code (\u0027Code Injection\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/94.html"}]},{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61","version":"2025","organization":"OWASP Foundation","informationUri":"https://top10.owasp.org/2025/","isComprehensive":false,"shortDescription":{"text":"The OWASP Top 10:2025 web application security risks."},"taxa":[{"id":"A01:2025","guid":"df693558-c822-0452-8f7b-4d53cb6bcc59","name":"Broken Access Control","shortDescription":{"text":"Broken Access Control"},"helpUri":"https://top10.owasp.org/2025/A01_2025-Broken_Access_Control/"},{"id":"A02:2025","guid":"668dee9e-41bc-6354-97d0-fdf8f40c50c1","name":"Security Misconfiguration","shortDescription":{"text":"Security Misconfiguration"},"helpUri":"https://top10.owasp.org/2025/A02_2025-Security_Misconfiguration/"},{"id":"A03:2025","guid":"168e227c-7735-2e57-bc6e-997affe644c5","name":"Software Supply Chain Failures","shortDescription":{"text":"Software Supply Chain Failures"},"helpUri":"https://top10.owasp.org/2025/A03_2025-Software_Supply_Chain_Failures/"},{"id":"A04:2025","guid":"6a9f5bfd-1a56-6453-beec-a7eff0ba3007","name":"Cryptographic Failures","shortDescription":{"text":"Cryptographic Failures"},"helpUri":"https://top10.owasp.org/2025/A04_2025-Cryptographic_Failures/"},{"id":"A05:2025","guid":"87e86033-3231-8458-8e4a-5cb82743553a","name":"Injection","shortDescription":{"text":"Injection"},"helpUri":"https://top10.owasp.org/2025/A05_2025-Injection/"},{"id":"A07:2025","guid":"334ddd78-539d-d35c-83dd-253647eb7eaf","name":"Authentication Failures","shortDescription":{"text":"Authentication Failures"},"helpUri":"https://top10.owasp.org/2025/A07_2025-Authentication_Failures/"},{"id":"A08:2025","guid":"84b0c297-710e-9a5f-9335-936ecb260c36","name":"Software or Data Integrity Failures","shortDescription":{"text":"Software or Data Integrity Failures"},"helpUri":"https://top10.owasp.org/2025/A08_2025-Software_or_Data_Integrity_Failures/"}]},{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35","organization":"OWASP Foundation","informationUri":"https://owasp.org/www-project-top-10-ci-cd-security-risks/","isComprehensive":false,"shortDescription":{"text":"The OWASP Top 10 CI/CD Security Risks."},"taxa":[{"id":"CICD-SEC-5","guid":"cc7f4610-8859-e654-9029-d5f97d992220","name":"Insufficient PBAC (Pipeline-Based Access Controls)","shortDescription":{"text":"Insufficient PBAC (Pipeline-Based Access Controls)"},"helpUri":"https://owasp.github.io/www-project-top-10-ci-cd-security-risks/CICD-SEC-05-Insufficient-PBAC"},{"id":"CICD-SEC-9","guid":"b3d36727-0395-5b51-94c4-5e173d62eab3","name":"Improper Artifact Integrity Validation","shortDescription":{"text":"Improper Artifact Integrity Validation"},"helpUri":"https://owasp.github.io/www-project-top-10-ci-cd-security-risks/CICD-SEC-09-Improper-Artifact-Integrity-Validation"}]}],"properties":{"codehealthPublication":{"public":true,"notice":"This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings \u2014 which rule fired, in which file, on which line, and how to fix it \u2014 are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.","securityFindingsRedacted":33,"secretScannerRunsExcluded":0}},"redactionTokens":["A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."]}]}