$children */ public function __construct( public array $children, public ?Transform $transform = null, public ?string $id = null, public ?string $class = null ) { } public function getElementType(): string { return 'g'; } public function getAttributes(): array { $attributes = []; if ($this->transform !== null && $this->transform->hasTransformations()) { $attributes['transform'] = $this->transform->toSvgValue(); } if ($this->id !== null) { $attributes['id'] = $this->id; } if ($this->class !== null) { $attributes['class'] = $this->class; } return $attributes; } public function hasTransform(): bool { return $this->transform !== null && $this->transform->hasTransformations(); } public function getTransform(): ?Transform { return $this->transform; } public function toSvg(): string { $attributes = $this->getAttributes(); $attributeString = empty($attributes) ? '' : ' ' . $this->buildAttributeString($attributes); $childrenSvg = implode("\n ", array_map( fn (SvgElement $child) => $child->toSvg(), $this->children )); if (empty($childrenSvg)) { return ""; } return "\n {$childrenSvg}\n"; } private function buildAttributeString(array $attributes): string { $parts = []; foreach ($attributes as $key => $value) { $parts[] = sprintf('%s="%s"', $key, htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8')); } return implode(' ', $parts); } }