// npm package
boring-avatars-vanilla
Boring avatars as a vanilla JavaScript library, SVG-based avatars from any username and color palette. Works in both browsers and Node.js server-side rendering.
versions
3
maintainers
1
license
MIT
first publish
2026-04-02
publisher
atool
tarball
46,541 B
AUTO-PUBLISHED·1 version indexed·latest published 2026-04-03
// publisher campaignby atool
9 caught packages from this accountThis is not an isolated catch. The same publisher has shipped 8 other packages that our pipeline flagged — the shape of a coordinated campaign, not a one-off. Each link below opens that sibling's analysis.
// offending code· @1.0.2· no static-pattern hits
llm: benign · 0.85→ No suspicious destination, no remote-exec shape — 1 known-vendor host(s).
- @1.0.2··AUTO-PUBLISHED·publisher: atoolheuristic 75/100static flags 0llm benign (0.85) via ollamapublisher-multi-name-burst:5osv-flagged:MAL-2026-4130
→ No suspicious destination, no remote-exec shape — 1 known-vendor host(s).
// offending code· no static-pattern hits
--- package.json (entry) --- { "name": "boring-avatars-vanilla", "version": "1.0.2", "description": "Boring avatars as a vanilla JavaScript library, SVG-based avatars from any username and color palette. Works in both browsers and Node.js server-side rendering.", "type": "module", "main": "./dist/index.cjs", "module": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js", "require": "./dist/index.cjs" } }, "umd": "./dist/index.umd.js", "files": [ "dist" ], "scripts": { "build": "tsc && vite build", "test": "vitest", "test:run": "vitest run", "dev": "vite" }, "keywords": [ "boring-avatars", "boring", "avatar", "svg", "vanilla", "javascript", "nodejs", "browser" ], "license": "MIT", "devDependencies": { "@types/node": "^22.0.0", "typescript": "~5.8.3", "vite": "^7.0.0", "vite-plugin-dts": "^4.5.4", "vitest": "^3.0.0" }, "repository": "git@github.com:hustcc/boring-avatars-vanilla.git" } --- index.js (entry) --- const S = (s) => { let e = 0; for (let r = 0; r < s.length; r++) { const a = s.charCodeAt(r); e = (e << 5) - e + a, e = e & e; } return Math.abs(e); }, z = (s, e) => Math.floor(s / Math.pow(10, e) % 10), y = (s, e) => !(z(s, e) % 2), p = (s, e, r) => { const a = s % e; return r && z(s, r) % 2 === 0 ? -a : a; }, w = (s, e, r) => e[s % r], E = (s) => { s.slice(0, 1) === "#" && (s = s.slice(1)); const e = parseInt(s.substr(0, 2), 16), r = parseInt(s.substr(2, 2), 16), a = parseInt(s.substr(4, 2), 16); return (e * 299 + r * 587 + a * 114) / 1e3 >= 128 ? "#000000" : "#FFFFFF"; }; let U = 0; const k = () => `boring-avatar-${++U}-${Date.now().toString(36)}`, _ = 3, h = 80; function B(s, e) { const r = S(s), a = e.length; return Array.from({ length: _ }, (n, t) => ({ color: w(r + t, e, a), translateX: p(r * (t + 1), h / 10, 1), translateY: p(r * (t + 1), h / 10, 2), scale: 1.2 + p(r * (t + 1), h / 20) / 10, rotate: p(r * (t + 1), 360, 1) })); } const M = (s) => { const { name: e, colors: r, title: a, square: o, size: n = "40px" } = s, t = B(e, r), i = k(), c = typeof n == "number" ? `${n}px` : n, f = o ? `<rect width="${h}" height="${h} --- bundled output (OSV-MAL flagged — LLM scope expansion) --- --- dist/index.cjs (bundled) --- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const S=s=>{let e=0;for(let r=0;r<s.length;r++){const a=s.charCodeAt(r);e=(e<<5)-e+a,e=e&e}return Math.abs(e)},M=(s,e)=>Math.floor(s/Math.pow(10,e)%10),y=(s,e)=>!(M(s,e)%2),p=(s,e,r)=>{const a=s%e;return r&&M(s,r)%2===0?-a:a},w=(s,e,r)=>e[s%r],_=s=>{s.slice(0,1)==="#"&&(s=s.slice(1));const e=parseInt(s.substr(0,2),16),r=parseInt(s.substr(2,2),16),a=parseInt(s.substr(4,2),16);return(e*299+r*587+a*114)/1e3>=128?"#000000":"#FFFFFF"};let U=0;const k=()=>`boring-avatar-${++U}-${Date.now().toString(36)}`,B=3,h=80;function L(s,e){const r=S(s),a=e.length;return Array.from({length:B},(n,t)=>({color:w(r+t,e,a),translateX:p(r*(t+1),h/10,1),translateY:p(r*(t+1),h/10,2),scale:1.2+p(r*(t+1),h/20)/10,rotate:p(r*(t+1),360,1)}))}const z=s=>{const{name:e,colors:r,title:a,square:o,size:n="40px"}=s,t=L(e,r),i=k(),c=typeof n=="number"?`${n}px`:n,f=o?`<rect width="${h}" height="${h}" fill="#FFFFFF" />`:`<rect width="${h}" height="${h}" rx="${h*2}" fill="#FFFFFF" />`;return`<svg viewBox="0 0 ${h} ${h}" fill="none" role="img" xmlns="http://www.w3.org/2000/svg" width="${c}" height="${c}" > ${a?`<title>${e}</title>`:""} <mask id="${i}" maskUnits="userSpaceOnUse" x="0" y="0" width="${h}" height="${h}"> ${f} </mask> <g mask="url(#${i})"> <rect width="${h}" height="${h}" fill="${t[0].color}" /> <path filter="url(#filter_${i})" d="M32.414 59.35L50.376 70.5H72.5v-71H33.728L26.5 13.381l19.057 27.08L32.414 59.35z" fill="${t[1].color}" transform="translate(${t[1].translateX} ${t[1].translateY}) rotate(${t[1].rotate} ${h/2} ${h/2}) scale(${t[2].scale})" /> <path filter="url(#filter_${i})" style="mix-blend-mode: overlay" d="M22.216 24L0 46.75l14.108 38.129L78 86l-3.081-59.276-22.378 4.005 12.972 20.186-23.35 27.395L22.215 24z" fill="${t[2].color}" transform="translate(${t[2].translateX} ${t[2].translate --- dist/index.d.ts (bundled) --- import { AvatarProps, AvatarVariant } from './types.js'; export type { AvatarProps, AvatarVariant }; /** * Generate an SVG avatar * @param props - Avatar configuration options * @returns SVG string * * @example * ```ts * import boring from 'boring-avatars-vanilla'; * * const svg = boring({ * name: 'John Doe', * variant: 'beam', * size: 40, * colors: ['#92A1C6', '#146A7C', '#F0AB3D'] * }); * * // Use in browser * document.getElementById('avatar').innerHTML = svg; * * // Use in Node.js * fs.writeFileSync('avatar.svg', svg); * ``` */ declare function boring(props?: AvatarProps): string; export { boring }; export default boring; //# sourceMappingURL=index.d.ts.map --- dist/index.js (bundled) --- const S = (s) => { let e = 0; for (let r = 0; r < s.length; r++) { const a = s.charCodeAt(r); e = (e << 5) - e + a, e = e & e; } return Math.abs(e); }, z = (s, e) => Math.floor(s / Math.pow(10, e) % 10), y = (s, e) => !(z(s, e) % 2), p = (s, e, r) => { const a = s % e; return r && z(s, r) % 2 === 0 ? -a : a; }, w = (s, e, r) => e[s % r], E = (s) => { s.slice(0, 1) === "#" && (s = s.slice(1)); const e = parseInt(s.substr(0, 2), 16), r = parseInt(s.substr(2, 2), 16), a = parseInt(s.substr(4, 2), 16); return (e * 299 + r * 587 + a * 114) / 1e3 >= 128 ? "#000000" : "#FFFFFF"; }; let U = 0; const k = () => `boring-avatar-${++U}-${Date.now().toString(36)}`, _ = 3, h = 80; function B(s, e) { const r = S(s), a = e.length; return Array.from({ length: _ }, (n, t) => ({ color: w(r + t, e, a), translateX: p(r * (t + 1), h / 10, 1), translateY: p(r * (t + 1), h / 10, 2), scale: 1.2 + p(r * (t + 1), h / 20) / 10, rotate: p(r * (t + 1), 360, 1) })); } const M = (s) => { const { name: e, colors: r, title: a, square: o, size: n = "40px" } = s, t = B(e, r), i = k(), c = typeof n == "number" ? `${n}px` : n, f = o ? `<rect width="${h}" height="${h}" fill="#FFFFFF" />` : `<rect width="${h}" height="${h}" rx="${h * 2}" fill="#FFFFFF" />`; return `<svg viewBox="0 0 ${h} ${h}" fill="none" role="img" xmlns="http://www.w3.org/2000/svg" width="${c}" height="${c}" > ${a ? `<title>${e}</title>` : ""} <mask id="${i}" maskUnits="userSpaceOnUse" x="0" y="0" width="${h}" height="${h}"> ${f} </mask> <g mask="url(#${i})"> <rect width="${h}" height="${h}" fill="${t[0].color}" /> <path filter="url(#filter_${i})" d="M32.414 59.35L50.376 70.5H72.5v-71H33.728L26.5 13.381l19.057 27.08L32.414 59.35z" fill="${t[1].color}" transform="translate(${t[1].translateX} ${t[1].translateY}) rotate(${t[1].rotate} ${h / 2} ${h / 2}) scale(${t[2].scale})" /> <path filter="url(#filter_${i})" --- dist/index.umd.js (bundled) --- (function(w,u){typeof exports=="object"&&typeof module<"u"?u(exports):typeof define=="function"&&define.amd?define(["exports"],u):(w=typeof globalThis<"u"?globalThis:w||self,u(w.BoringAvatars={}))})(this,(function(w){"use strict";const u=s=>{let e=0;for(let r=0;r<s.length;r++){const o=s.charCodeAt(r);e=(e<<5)-e+o,e=e&e}return Math.abs(e)},C=(s,e)=>Math.floor(s/Math.pow(10,e)%10),v=(s,e)=>!(C(s,e)%2),g=(s,e,r)=>{const o=s%e;return r&&C(s,r)%2===0?-o:o},x=(s,e,r)=>e[s%r],E=s=>{s.slice(0,1)==="#"&&(s=s.slice(1));const e=parseInt(s.substr(0,2),16),r=parseInt(s.substr(2,2),16),o=parseInt(s.substr(4,2),16);return(e*299+r*587+o*114)/1e3>=128?"#000000":"#FFFFFF"};let _=0;const y=()=>`boring-avatar-${++_}-${Date.now().toString(36)}`,T=3,h=80;function U(s,e){const r=u(s),o=e.length;return Array.from({length:T},(n,t)=>({color:x(r+t,e,o),translateX:g(r*(t+1),h/10,1),translateY:g(r*(t+1),h/10,2),scale:1.2+g(r*(t+1),h/20)/10,rotate:g(r*(t+1),360,1)}))}const M=s=>{const{name:e,colors:r,title:o,square:a,size:n="40px"}=s,t=U(e,r),i=y(),c=typeof n=="number"?`${n}px`:n,p=a?`<rect width="${h}" height="${h}" fill="#FFFFFF" />`:`<rect width="${h}" height="${h}" rx="${h*2}" fill="#FFFFFF" />`;return`<svg viewBox="0 0 ${h} ${h}" fill="none" role="img" xmlns="http://www.w3.org/2000/svg" width="${c}" height="${c}" > ${o?`<title>${e}</title>`:""} <mask id="${i}" maskUnits="userSpaceOnUse" x="0" y="0" width="${h}" height="${h}"> ${p} </mask> <g mask="url(#${i})"> <rect width="${h}" height="${h}" fill="${t[0].color}" /> <path filter="url(#filter_${i})" d="M32.414 59.35L50.376 70.5H72.5v-71H33.728L26.5 13.381l19.057 27.08L32.414 59.35z" fill="${t[1].color}" transform="translate(${t[1].translateX} ${t[1].translateY}) rotate(${t[1].rotate} ${h/2} ${h/2}) scale(${t[2].scale})" /> <path filter="url(#filter_${i})" style="mix-blend-mode: overlay" d="M22.216 24L0 46.75l14.108 38.129L78 86l-3.081-59.276-22.378 4.005 12.972 --- dist/types.d.ts (bundled) --- export type AvatarVariant = 'pixel' | 'bauhaus' | 'ring' | 'beam' | 'sunset' | 'marble' | 'geometric' | 'abstract'; export interface AvatarProps { /** The name to generate the avatar from */ name?: string; /** Array of colors to use in the avatar */ colors?: string[]; /** Include a title element in the SVG */ title?: boolean; /** Make the avatar square instead of round */ square?: boolean; /** Size of the avatar (number for pixels, or string with unit) */ size?: number | string; /** Variant style of the avatar */ variant?: AvatarVariant; } export interface AvatarResult { /** The SVG string */ svg: string; /** The generated avatar data (for advanced use) */ data: { name: string; colors: string[]; size: string; square: boolean; variant: AvatarVariant; }; } //# sourceMappingURL=types.d.ts.map --- dist/utilities.d.ts (bundled) --- export declare const hashCode: (name: string) => number; export declare const getModulus: (num: number, max: number) => number; export declare const getDigit: (number: number, ntn: number
