chore: remove Jenkinsfile for ailab service

This commit deletes the Jenkinsfile associated with the ailab service as part of a project cleanup.

Signed-off-by: zhenyus <zhenyus@mathmast.com>
This commit is contained in:
zhenyus 2025-07-14 16:31:16 +08:00
parent 32a40173da
commit ba442e40c0
14 changed files with 504 additions and 35 deletions

View File

@ -1,35 +0,0 @@
library 'first-class-pipeline'
executeFreeleapsPipeline {
serviceName = 'aml-services'
environmentSlug = 'alpha'
serviceGitBranch = 'dev'
serviceGitRepo = "https://gitea.freeleaps.mathmast.com/freeleaps/aml-services.git"
serviceGitRepoType = 'monorepo'
serviceGitCredentialsId = 'freeleaps-repos-gitea-credentails'
executeMode = 'on-demand'
commitMessageLintEnabled = false
components = [
[
name: 'ailab',
root: 'apps/ailab',
language: 'python',
dependenciesManager: 'pip',
requirementsFile: 'requirements.txt',
buildCacheEnabled: true,
buildAgentImage: 'python:3.10-slim-buster',
buildArtifacts: ['.'],
lintEnabled: false,
sastEnabled: false,
imageRegistry: 'docker.io',
imageRepository: 'freeleaps',
imageName: 'ailab',
imageBuilder: 'dind',
dockerfilePath: 'Dockerfile',
imageBuildRoot: '.',
imageReleaseArchitectures: ['linux/amd64', 'linux/arm64/v8'],
registryCredentialsId: 'freeleaps-devops-docker-hub-credentials',
semanticReleaseEnabled: true
]
]
}

34
aml-services/alpha/ci/Jenkinsfile vendored Normal file
View File

@ -0,0 +1,34 @@
library 'first-class-pipeline'
executeFreeleapsPipeline {
serviceName = 'aml-services'
environmentSlug = 'alpha'
serviceGitBranch = 'dev'
serviceGitRepo = "https://gitea.freeleaps.mathmast.com/freeleaps/aml-services.git"
serviceGitRepoType = 'monorepo'
serviceGitCredentialsId = 'aml-services-git-repo-credentials'
executeMode = 'fully'
commitMessageLintEnabled = false
components = [
[
name: 'ailab',
root: 'apps/ailab',
language: 'python',
dependenciesManager: 'pip',
buildCacheEnabled: true,
buildAgentImage: 'python:3.10-slim-bullseye',
buildArtifacts: ['.'],
lintEnabled: false,
sastEnabled: false,
imageRegistry: 'docker.io',
imageRepository: 'freeleaps',
imageName: 'ailab',
imageBuilder: 'dind',
dockerfilePath: 'Dockerfile',
imageBuildRoot: '.',
imageReleaseArchitectures: ['linux/amd64', 'linux/arm64/v8'],
registryCredentialsId: 'freeleaps-devops-docker-hub-credentials',
semanticReleaseEnabled: true
]
]
}

View File

@ -0,0 +1,6 @@
apiVersion: v2
name: ailab
description: A Helm Chart of ailab, which part of Freeleaps Platform, powered by Freeleaps.
type: application
version: 0.0.1
appVersion: "0.0.1"

View File

@ -0,0 +1,21 @@
apiVersion: v1
kind: Secret
metadata:
name: ailab-config
namespace: {{ .Release.Namespace }}
type: Opaque
data:
SERVICE_API_ACCESS_HOST: {{ .Values.ailab.configs.serviceApiAccessHost | b64enc | quote }}
SERVICE_API_ACCESS_PORT: {{ .Values.ailab.configs.serviceApiAccessPort | toString | b64enc }}
CONTAINER_APP_ROOT: {{ .Values.ailab.configs.containerAppRoot | b64enc | quote }}
AZURE_TRANSLATION_API_KEY: {{ .Values.ailab.configs.azureTranslationApiKey | b64enc | quote }}
AZURE_TRANSLATION_API_LOCATION: {{ .Values.ailab.configs.azureTranslationApiLocation | b64enc | quote }}
AZURE_TRANSLATION_API_ENDPOINT: {{ .Values.ailab.configs.azureTranslationApiEndpoint | b64enc | quote }}
AZURE_DOCUMENT_TRANSLATION_API_ENDPOINT: {{ .Values.ailab.configs.azureDocumentTranslationApiEndpoint | b64enc | quote }}
AZURE_OPENAI_API_VERSION: {{ .Values.ailab.configs.azureOpenaiApiVersion | b64enc | quote }}
AZURE_OPENAI_API_KEY: {{ .Values.ailab.configs.azureOpenaiApiKey | b64enc | quote }}
AZURE_OPENAI_ENDPOINT: {{ .Values.ailab.configs.azureOpenaiEndpoint | b64enc | quote }}
ANTHROPIC_API_KEY: {{ .Values.ailab.configs.anthropicApiKey | b64enc | quote }}
ANTHROPIC_API_MODEL_VERSION: {{ .Values.ailab.configs.anthropicApiModelVersion | b64enc | quote }}
ANTHROPIC_API_MODEL_MAX_TOKEN: {{ .Values.ailab.configs.anthropicApiModelMaxToken | toString | b64enc }}
REDIS_URL: {{ .Values.ailab.configs.redisUrl | b64enc | quote }}

View File

@ -0,0 +1,27 @@
{{ $namespace := .Release.Namespace }}
{{ $appVersion := .Chart.AppVersion | quote }}
{{ $releaseCertificate := .Release.Service }}
{{ $releaseName := .Release.Name }}
{{- range $ingress := .Values.ailab.ingresses }}
{{- if not $ingress.tls.exists }}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: {{ $ingress.name }}
namespace: {{ $namespace }}
labels:
app.kubernetes.io/version: {{ $appVersion }}
app.kubernetes.io/name: {{ $ingress.name | quote }}
app.kubernetes.io/managed-by: {{ $releaseCertificate }}
app.kubernetes.io/instance: {{ $releaseName }}
spec:
commonName: {{ $ingress.host }}
dnsNames:
- {{ $ingress.host }}
issuerRef:
name: {{ $ingress.tls.issuerRef.name }}
kind: {{ $ingress.tls.issuerRef.kind }}
secretName: {{ $ingress.tls.name }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,97 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/name: "ailab"
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
name: "ailab"
namespace: {{ .Release.Namespace | quote }}
spec:
selector:
matchLabels:
app.kubernetes.io/name: "ailab"
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
replicas: {{ .Values.ailab.replicas }}
template:
metadata:
labels:
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/name: "ailab"
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
annotations:
app.kubernetes.io/config-checksum: {{ include (print $.Template.BasePath "/ailab/ailab-config.yaml") . | sha256sum }}
spec:
containers:
- name: "ailab"
image: "{{ coalesce .Values.ailab.image.registry .Values.global.registry "docker.io"}}/{{ coalesce .Values.ailab.image.repository .Values.global.repository }}/{{ .Values.ailab.image.name }}:{{ .Values.ailab.image.tag | default "latest" }}"
imagePullPolicy: {{ .Values.ailab.image.imagePullPolicy | default "IfNotPresent" }}
ports:
{{- range $port := .Values.ailab.ports }}
- containerPort: {{ $port.containerPort }}
name: {{ $port.name }}
protocol: {{ $port.protocol }}
{{- end }}
{{- if .Values.ailab.resources }}
resources:
{{- toYaml .Values.ailab.resources | nindent 12 }}
{{- end }}
{{- if .Values.ailab.probes }}
{{- if and (.Values.ailab.probes.liveness) (eq .Values.ailab.probes.liveness.type "httpGet") }}
livenessProbe:
httpGet:
path: {{ .Values.ailab.probes.liveness.config.path }}
port: {{ .Values.ailab.probes.liveness.config.port }}
{{- if .Values.ailab.probes.liveness.config.initialDelaySeconds }}
initialDelaySeconds: {{ .Values.ailab.probes.liveness.config.initialDelaySeconds }}
{{- end }}
{{- if .Values.ailab.probes.liveness.config.periodSeconds }}
periodSeconds: {{ .Values.ailab.probes.liveness.config.periodSeconds }}
{{- end }}
{{- if .Values.ailab.probes.liveness.config.timeoutSeconds }}
timeoutSeconds: {{ .Values.ailab.probes.liveness.config.timeoutSeconds }}
{{- end }}
{{- if .Values.ailab.probes.liveness.config.successThreshold }}
successThreshold: {{ .Values.ailab.probes.liveness.config.successThreshold }}
{{- end }}
{{- if .Values.ailab.probes.liveness.config.failureThreshold }}
failureThreshold: {{ .Values.ailab.probes.liveness.config.failureThreshold }}
{{- end }}
{{- if .Values.ailab.probes.liveness.config.terminationGracePeriodSeconds }}
terminationGracePeriodSeconds: {{ .Values.ailab.probes.liveness.config.terminationGracePeriodSeconds }}
{{- end }}
{{- end }}
{{- if and (.Values.ailab.probes.readiness) (eq .Values.ailab.probes.readiness.type "httpGet") }}
readinessProbe:
httpGet:
path: {{ .Values.ailab.probes.readiness.config.path }}
port: {{ .Values.ailab.probes.readiness.config.port }}
{{- if .Values.ailab.probes.readiness.config.initialDelaySeconds }}
initialDelaySeconds: {{ .Values.ailab.probes.readiness.config.initialDelaySeconds }}
{{- end }}
{{- if .Values.ailab.probes.readiness.config.periodSeconds }}
periodSeconds: {{ .Values.ailab.probes.readiness.config.periodSeconds }}
{{- end }}
{{- if .Values.ailab.probes.readiness.config.timeoutSeconds }}
timeoutSeconds: {{ .Values.ailab.probes.readiness.config.timeoutSeconds }}
{{- end }}
{{- if .Values.ailab.probes.readiness.config.successThreshold }}
successThreshold: {{ .Values.ailab.probes.readiness.config.successThreshold }}
{{- end }}
{{- if .Values.ailab.probes.readiness.config.failureThreshold }}
failureThreshold: {{ .Values.ailab.probes.readiness.config.failureThreshold }}
{{- end }}
{{- end }}
{{- end}}
env:
{{- range $key, $value := .Values.ailab.configs }}
- name: {{ $key | snakecase | upper }}
valueFrom:
secretKeyRef:
name: ailab-config
key: {{ $key | snakecase | upper }}
{{- end }}

View File

@ -0,0 +1,36 @@
{{ $namespace := .Release.Namespace }}
{{ $appVersion := .Chart.AppVersion | quote }}
{{ $releaseIngress := .Release.Service }}
{{ $releaseName := .Release.Name }}
{{- range $ingress := .Values.ailab.ingresses }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $ingress.name }}
namespace: {{ $namespace }}
labels:
app.kubernetes.io/version: {{ $appVersion }}
app.kubernetes.io/name: {{ $ingress.name | quote }}
app.kubernetes.io/managed-by: {{ $releaseIngress }}
app.kubernetes.io/instance: {{ $releaseName }}
spec:
{{- if $ingress.class }}
ingressClassName: {{ $ingress.class }}
{{- end }}
{{- if $ingress.tls }}
tls:
- hosts:
- {{ $ingress.host }}
{{- if $ingress.tls.exists }}
secretName: {{ $ingress.tls.secretRef.name }}
{{- else }}
secretName: {{ $ingress.tls.name }}
{{- end }}
{{- end }}
rules:
- host: {{ $ingress.host }}
http:
paths:
{{- toYaml $ingress.rules | nindent 10 }}
{{- end }}

View File

@ -0,0 +1,26 @@
{{ $namespace := .Release.Namespace }}
{{ $appVersion := .Chart.AppVersion | quote }}
{{ $releaseService := .Release.Service }}
{{ $releaseName := .Release.Name }}
{{- range $service := .Values.ailab.services }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ $service.name }}
namespace: {{ $namespace }}
labels:
app.kubernetes.io/version: {{ $appVersion }}
app.kubernetes.io/name: {{ $service.name | quote }}
app.kubernetes.io/managed-by: {{ $releaseService }}
app.kubernetes.io/instance: {{ $releaseName }}
spec:
ports:
- port: {{ $service.port }}
targetPort: {{ $service.targetPort }}
selector:
app.kubernetes.io/version: {{ $appVersion }}
app.kubernetes.io/name: "ailab"
app.kubernetes.io/managed-by: {{ $releaseService }}
app.kubernetes.io/instance: {{ $releaseName }}
{{- end }}

View File

@ -0,0 +1,40 @@
{{ $namespace := .Release.Namespace }}
{{ $appVersion := .Chart.AppVersion | quote }}
{{ $releaseService := .Release.Service }}
{{ $releaseName := .Release.Name }}
{{- range $service := .Values.ailab.services }}
{{- if $service.serviceMonitor.enabled }}
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ $service.name }}-monitor
namespace: {{ $service.serviceMonitor.namespace }}
labels:
app.kubernetes.io/version: {{ $appVersion }}
app.kubernetes.io/name: {{ $service.name }}-monitor
app.kubernetes.io/managed-by: {{ $releaseService }}
app.kubernetes.io/instance: {{ $releaseName }}
{{- if $service.serviceMonitor.labels }}
{{- toYaml $service.serviceMonitor.labels | nindent 4 }}
{{- end }}
spec:
endpoints:
- path: /api/_/metrics
targetPort: {{ $service.targetPort }}
{{- if $service.serviceMonitor.interval }}
interval: {{ $service.serviceMonitor.interval }}
{{- end }}
{{- if $service.serviceMonitor.scrapeTimeout }}
scrapeTimeout: {{ $service.serviceMonitor.scrapeTimeout }}
{{- end }}
namespaceSelector:
matchNames:
- {{ $namespace | quote }}
selector:
matchLabels:
app.kubernetes.io/name: {{ $service.name }}
app.kubernetes.io/instance: {{ $releaseName }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,32 @@
{{- if .Values.ailab.vpa }}
---
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: {{ .Release.Name }}-vpa
namespace: {{ .Release.Namespace }}
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: ailab
resourcePolicy:
containerPolicies:
- containerName: '*'
{{- if .Values.ailab.vpa.minAllowed.enabled }}
minAllowed:
cpu: {{ .Values.ailab.vpa.minAllowed.cpu }}
memory: {{ .Values.ailab.vpa.minAllowed.memory }}
{{- end }}
{{- if .Values.ailab.vpa.maxAllowed.enabled }}
maxAllowed:
cpu: {{ .Values.ailab.vpa.maxAllowed.cpu }}
memory: {{ .Values.ailab.vpa.maxAllowed.memory }}
{{- end }}
{{- if .Values.ailab.vpa.controlledResources }}
controlledResources:
{{- range .Values.ailab.vpa.controlledResources }}
- {{ . }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,65 @@
global:
registry: docker.io
repository: freeleaps
nodeSelector: {}
ailab:
replicas: 1
image:
registry:
repository: freeleaps
name: ailab
tag: 0.0.1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8009
protocol: TCP
resources:
requests:
cpu: "0.1"
memory: "64Mi"
limits:
cpu: "0.2"
memory: "128Mi"
probes: {}
services:
- name: ailab-service
type: ClusterIP
port: 8009
targetPort: 8009
serviceMonitor:
enabled: false
labels:
release: kube-prometheus-stack
namespace: freeleaps-monitoring-system
interval: 30s
scrapeTimeout: ""
# Defaults to {}, which means doesn't have any ingress
ingresses: {}
configs:
serviceApiAccessHost: "0.0.0.0"
serviceApiAccessPort: 8009
containerAppRoot: /app
azureTranslationApiKey: "eaf4c14eb06b4cd790e90111dc6e9f57"
azureTranslationApiLocation: "global"
azureTranslationApiEndpoint: "https://api.cognitive.microsofttranslator.com"
azureDocumentTranslationApiEndpoint: "https://freeleaps-translation.cognitiveservices.azure.com/"
azureOpenaiApiVersion: "2024-08-06"
azureOpenaiApiKey: "BZWqFEpDiMFMAdJvGKeDisjwepqEQpKDH8R9R8Yjp8GFXCRqjeuzJQQJ99ALAC4f1cMXJ3w3AAABACOGrMqX"
azureOpenaiEndpoint: "https://freeleaps-azure-openai.openai.azure.com/"
anthropicApiKey: "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"
anthropicApiModelVersion: "claude-3-5-sonnet-20241022"
anthropicApiModelMaxToken: 1024
redisUrl: "redis://freeleaps-alpha-redis-master.freeleaps-alpha.svc.freeleaps.cluster:6379"
vpa:
minAllowed:
enabled: false
cpu: 100m
memory: 64Mi
maxAllowed:
enabled: true
cpu: 200m
memory: 128Mi
controlledResources:
- cpu
- memory

View File

@ -0,0 +1,65 @@
global:
registry: docker.io
repository: freeleaps
nodeSelector: {}
ailab:
replicas: 1
image:
registry:
repository: freeleaps
name: ailab
tag: 0.0.1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8009
protocol: TCP
resources:
requests:
cpu: "0.1"
memory: "64Mi"
limits:
cpu: "0.2"
memory: "128Mi"
probes: {}
services:
- name: ailab-service
type: ClusterIP
port: 8009
targetPort: 8009
serviceMonitor:
enabled: false
labels:
release: kube-prometheus-stack
namespace: freeleaps-monitoring-system
interval: 30s
scrapeTimeout: ""
# Defaults to {}, which means doesn't have any ingress
ingresses: {}
configs:
serviceApiAccessHost: "0.0.0.0"
serviceApiAccessPort: 8009
containerAppRoot: /app
azureTranslationApiKey: "eaf4c14eb06b4cd790e90111dc6e9f57"
azureTranslationApiLocation: "global"
azureTranslationApiEndpoint: "https://api.cognitive.microsofttranslator.com"
azureDocumentTranslationApiEndpoint: "https://freeleaps-translation.cognitiveservices.azure.com/"
azureOpenaiApiVersion: "2024-08-06"
azureOpenaiApiKey: "BZWqFEpDiMFMAdJvGKeDisjwepqEQpKDH8R9R8Yjp8GFXCRqjeuzJQQJ99ALAC4f1cMXJ3w3AAABACOGrMqX"
azureOpenaiEndpoint: "https://freeleaps-azure-openai.openai.azure.com/"
anthropicApiKey: "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"
anthropicApiModelVersion: "claude-3-5-sonnet-20241022"
anthropicApiModelMaxToken: 1024
redisUrl: "redis://freeleaps-alpha-redis-master.freeleaps-alpha.svc.freeleaps.cluster:6379"
vpa:
minAllowed:
enabled: false
cpu: 100m
memory: 64Mi
maxAllowed:
enabled: true
cpu: 200m
memory: 128Mi
controlledResources:
- cpu
- memory

View File

55
diagrams/workflow.drawio Normal file
View File

@ -0,0 +1,55 @@
<mxfile host="65bd71144e">
<diagram id="pfT734yZ9old_O5NwZa7" name="Page-1">
<mxGraphModel dx="906" dy="659" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="4" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="2" target="3" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="2" value="Source Code Fetching" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="40" y="40" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="6" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="3" target="5" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="3" value="Commit Message&lt;div&gt;Linting&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="40" y="160" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="8" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="5" target="7" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="5" value="Dependencies Resolving" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="40" y="280" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="10" style="edgeStyle=none;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="7" target="9" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="7" value="Build Agent&lt;div&gt;Setup&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="40" y="400" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="12" style="edgeStyle=none;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="9" target="11" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="9" value="Compilation &amp;amp; Packaging" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="260" y="400" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="14" style="edgeStyle=none;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="11" target="13" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="11" value="Image Building" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="260" y="280" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="16" style="edgeStyle=none;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="13" target="15" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="13" value="Image Pushing" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="260" y="160" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="15" value="Argo Application&lt;div&gt;Version Updating&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="260" y="40" width="120" height="60" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>