Complete Migration Guide: Sonatype Nexus to CloudRepo
Step-by-step guide to migrate from Sonatype Nexus Repository to CloudRepo. Save 90%+ on costs while simplifying repository management with our zero-downtime migration process.
Migrating from Sonatype Nexus Repository to CloudRepo can reduce your repository management costs by 90% or more while eliminating infrastructure overhead. This comprehensive guide walks you through every step of a successful migration, from initial planning to production cutover.
Why Teams Are Migrating from Nexus
Organizations worldwide are moving from self-hosted Nexus installations to CloudRepo for compelling reasons. Whether you’re hosting Maven repositories, Python packages, or Docker images, here’s why teams are making the switch:
Dramatic Cost Reduction
- 90%+ cost savings compared to Nexus infrastructure and licensing
- No hidden infrastructure costs - eliminate servers, storage, networking, and maintenance
- Predictable monthly pricing - no surprise bills for storage or bandwidth
- No expensive support contracts - support included with all CloudRepo plans
Simplified Management
- Zero infrastructure overhead - no servers to patch, upgrade, or monitor
- Automatic scaling - handle traffic spikes without manual intervention
- Built-in high availability - enterprise redundancy without the complexity
- 5-minute setup vs weeks of Nexus configuration
Superior Developer Experience
- Faster artifact downloads - global CDN vs single Nexus server
- No VPN required - secure cloud access from anywhere
- Better CI/CD integration - native support for modern pipelines
- 99.9% uptime SLA - more reliable than most self-hosted setups
Real Customer Result: “We reduced our repository costs from $3,800/month with Nexus to $299/month with CloudRepo - a 92% savings!” - DevOps Lead, FinTech Startup
Migration Overview
Migrating from Nexus to CloudRepo is straightforward and can be completed with zero downtime. Here’s what the process involves:
What Gets Migrated
- All repository types: Maven, Gradle, Python, npm, Docker, Raw, and more
- Artifacts and metadata: Complete preservation of your artifact history
- Users and permissions: Map Nexus roles to CloudRepo’s permission model
- Repository configurations: Proxy, hosted, and group repositories
- Build tool configurations: Update Maven, Gradle, pip, npm settings
Timeline Expectations
Most migrations follow this timeline:
- Small teams (< 10GB): 1-2 days
- Medium teams (10-100GB): 3-5 days
- Large teams (100GB-1TB): 1-2 weeks
- Enterprise (> 1TB): 2-4 weeks with CloudRepo migration assistance
Zero-Downtime Migration Strategy
Our proven approach ensures continuous service during migration:
- Dual-running period: Keep Nexus operational while setting up CloudRepo
- Incremental sync: Migrate artifacts in batches without disrupting builds
- Gradual cutover: Move teams progressively to minimize risk
- Rollback capability: Maintain ability to revert if needed
Pre-Migration Checklist
Before starting your migration, complete this preparation checklist:
1. Audit Current Nexus Usage
# Check total storage usagedu -sh /path/to/nexus-data/blobs
# Count total artifactsfind /path/to/nexus-data/blobs -type f | wc -l
# List all repositoriescurl -u admin:password https://nexus.example.com/service/rest/v1/repositories2. Identify Active Repositories
Document which repositories are actively used:
- Production repositories vs development/test
- Public proxy repositories being used
- Custom repository groups
- Repository cleanup policies
3. Document Access Patterns
- List all users and service accounts
- Map current permissions and roles
- Identify CI/CD systems accessing Nexus
- Document any custom integrations or scripts
4. Review Security Requirements
- SSL/TLS certificate requirements
- IP whitelisting needs
- Compliance requirements (SOC 2, HIPAA, etc.)
- Audit logging requirements
Pro Tip: Export your Nexus configuration for reference: curl -u admin:password https://nexus.example.com/service/rest/v1/repositories > nexus-repos.json
Step-by-Step Migration Process
Step 1: Create CloudRepo Account and Repositories
Start by setting up your CloudRepo environment:
# 1. Sign up for CloudRepo free trial at https://cloudrepo.io/signup
# 2. Create repositories matching your Nexus structure# Example: Creating a Maven repository via CloudRepo APIcurl -X POST https://api.cloudrepo.io/repositories \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "maven-releases", "type": "maven2", "storage": "hosted" }'Step 2: Configure Authentication
Set up authentication for your teams:
<!-- Maven settings.xml --><settings> <servers> <server> <id>cloudrepo-releases</id> <username>your-username</username> <password>your-token</password> </server> <server> <id>cloudrepo-snapshots</id> <username>your-username</username> <password>your-token</password> </server> </servers></settings>Step 3: Migrate Maven/Gradle Artifacts
Use our migration script for bulk transfers:
#!/bin/bash# CloudRepo Maven Migration Script
NEXUS_URL="https://nexus.example.com"CLOUDREPO_URL="https://YOUR_ORG.cloudrepo.io"NEXUS_REPO="maven-releases"CLOUDREPO_REPO="maven-releases"
# Download artifacts from Nexusmvn dependency:get \ -DremoteRepositories=$NEXUS_URL/repository/$NEXUS_REPO \ -Dartifact=GROUP:ARTIFACT:VERSION
# Upload to CloudRepomvn deploy:deploy-file \ -DrepositoryId=cloudrepo-releases \ -Durl=$CLOUDREPO_URL/repository/$CLOUDREPO_REPO \ -DgroupId=GROUP \ -DartifactId=ARTIFACT \ -Dversion=VERSION \ -Dfile=./path/to/artifact.jarFor large-scale migrations, use our bulk migration tool:
# bulk_migrate.py - CloudRepo Bulk Migration Toolimport requestsimport osfrom concurrent.futures import ThreadPoolExecutor
def migrate_artifact(artifact_path): """Migrate a single artifact from Nexus to CloudRepo""" # Download from Nexus nexus_url = f"{NEXUS_BASE}/repository/{artifact_path}" response = requests.get(nexus_url, auth=(NEXUS_USER, NEXUS_PASS))
# Upload to CloudRepo cloudrepo_url = f"{CLOUDREPO_BASE}/repository/{artifact_path}" headers = {"Authorization": f"Bearer {CLOUDREPO_TOKEN}"} upload_response = requests.put( cloudrepo_url, data=response.content, headers=headers )
return upload_response.status_code == 201
# Parallel migration for speedwith ThreadPoolExecutor(max_workers=10) as executor: results = executor.map(migrate_artifact, artifact_list)Step 4: Migrate Python Packages
For Python packages, update pip configuration:
# ~/.pip/pip.conf or pip.conf[global]index-url = https://YOUR_USERNAME:YOUR_PASSWORD@YOUR_ORG.cloudrepo.io/simple/extra-index-url = https://pypi.org/simple/Migrate existing packages:
# Download from Nexuspip download --index-url https://nexus.example.com/repository/pypi/simple/ \ --dest ./packages PACKAGE_NAME
# Upload to CloudRepotwine upload --repository-url https://YOUR_ORG.cloudrepo.io/pypi/ \ ./packages/*Step 5: Update CI/CD Pipelines
Update your CI/CD configurations to point to CloudRepo:
Jenkins Pipeline:
// Jenkinsfile - Before (Nexus)pipeline { environment { MAVEN_OPTS = '-Dmaven.repo.remote=https://nexus.example.com/repository/maven-public' }}
// Jenkinsfile - After (CloudRepo)pipeline { environment { MAVEN_OPTS = '-Dmaven.repo.remote=https://YOUR_ORG.cloudrepo.io/repository/maven-public' }}GitHub Actions:
# .github/workflows/build.yml - Before (Nexus)- name: Configure Maven run: | echo "<settings>...</settings>" > ~/.m2/settings.xml
# .github/workflows/build.yml - After (CloudRepo)- name: Configure Maven for CloudRepo run: | cat > ~/.m2/settings.xml << EOF <settings> <servers> <server> <id>cloudrepo</id> <username>${{ secrets.CLOUDREPO_USERNAME }}</username> <password>${{ secrets.CLOUDREPO_TOKEN }}</password> </server> </servers> <mirrors> <mirror> <id>cloudrepo</id> <url>https://YOUR_ORG.cloudrepo.io/repository/maven-public</url> <mirrorOf>*</mirrorOf> </mirror> </mirrors> </settings> EOFGitLab CI:
# .gitlab-ci.yml - After (CloudRepo)variables: MAVEN_OPTS: '-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository' MAVEN_SETTINGS_PATH: '$CI_PROJECT_DIR/.m2/settings.xml'
before_script: - echo "$CLOUDREPO_SETTINGS_XML" > $MAVEN_SETTINGS_PATHStep 6: Migrate Users and Permissions
Map Nexus roles to CloudRepo permissions:
| Nexus Role | CloudRepo Permission | Description |
|---|---|---|
| nx-admin | Admin | Full repository access |
| nx-deploy | Write | Deploy artifacts |
| nx-developer | Read | Download artifacts |
| nx-anonymous | Public Read | Public repository access |
Create users programmatically:
# Create users via CloudRepo APIcurl -X POST https://api.cloudrepo.io/users \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "email": "developer@example.com", "role": "developer", "repositories": ["maven-releases", "maven-snapshots"] }'Step 7: Test and Validate
Comprehensive testing checklist:
# 1. Test artifact downloadmvn dependency:get -DgroupId=com.example -DartifactId=test -Dversion=1.0.0
# 2. Test artifact uploadmvn deploy:deploy-file -Dfile=test.jar -DgroupId=com.example \ -DartifactId=test -Dversion=1.0.1 -Dpackaging=jar \ -DrepositoryId=cloudrepo -Durl=https://YOUR_ORG.cloudrepo.io/repository/maven-releases
# 3. Verify CI/CD pipelinegit push --force-with-lease # Trigger your CI/CD pipeline
# 4. Load test (optional)ab -n 1000 -c 10 https://YOUR_ORG.cloudrepo.io/repository/maven-public/com/example/test/1.0.0/test-1.0.0.jarStep 8: Cut Over Production
Execute the production cutover:
- Final sync: Run one last migration sync
- Update DNS (if using custom domain): Point repository.yourdomain.com to CloudRepo
- Switch configurations: Deploy updated settings to all systems
- Monitor closely: Watch logs and metrics for 24-48 hours
- Decommission Nexus: After validation period, safely shut down Nexus
Important: Keep Nexus in read-only mode for 30 days as a safety net before full decommissioning.
Repository Configuration Mapping
Understanding how Nexus concepts map to CloudRepo:
Nexus Maven Proxy → CloudRepo Proxy Repositories
<!-- Nexus proxy configuration --><proxy> <id>central</id> <url>https://repo.maven.apache.org/maven2</url></proxy>
<!-- CloudRepo equivalent --><repository> <id>cloudrepo-central-proxy</id> <url>https://YOUR_ORG.cloudrepo.io/repository/maven-central</url></repository>Nexus Hosted Repositories → CloudRepo Repositories
// build.gradle - Before (Nexus)repositories { maven { url "https://nexus.example.com/repository/maven-releases" credentials { username nexusUsername password nexusPassword } }}
// build.gradle - After (CloudRepo)repositories { maven { url "https://YOUR_ORG.cloudrepo.io/repository/maven-releases" credentials { username cloudrepoUsername password cloudrepoToken } }}Nexus Group Repositories → CloudRepo Repository Groups
CloudRepo supports repository groups for aggregating multiple repositories:
<!-- settings.xml for CloudRepo groups --><settings> <mirrors> <mirror> <id>cloudrepo-group</id> <mirrorOf>*</mirrorOf> <url>https://YOUR_ORG.cloudrepo.io/repository/maven-group</url> </mirror> </mirrors></settings>Python/PyPI Configuration
# pip.conf - Before (Nexus)[global]index-url = https://nexus.example.com/repository/pypi-all/simpletrusted-host = nexus.example.com
# pip.conf - After (CloudRepo)[global]index-url = https://USERNAME:TOKEN@YOUR_ORG.cloudrepo.io/simple/extra-index-url = https://pypi.org/simple/CI/CD Pipeline Updates
Jenkins Configuration Changes
Before (Nexus):
pipeline { agent any
environment { NEXUS_URL = 'https://nexus.example.com' NEXUS_REPOSITORY = 'maven-releases' NEXUS_CREDENTIALS = credentials('nexus-credentials') }
stages { stage('Deploy') { steps { sh ''' mvn deploy \ -DaltDeploymentRepository=nexus::default::${NEXUS_URL}/repository/${NEXUS_REPOSITORY} \ -Dusername=${NEXUS_CREDENTIALS_USR} \ -Dpassword=${NEXUS_CREDENTIALS_PSW} ''' } } }}After (CloudRepo):
pipeline { agent any
environment { CLOUDREPO_URL = 'https://YOUR_ORG.cloudrepo.io' CLOUDREPO_REPOSITORY = 'maven-releases' CLOUDREPO_CREDENTIALS = credentials('cloudrepo-credentials') }
stages { stage('Deploy to CloudRepo') { steps { sh ''' mvn deploy \ -DaltDeploymentRepository=cloudrepo::default::${CLOUDREPO_URL}/repository/${CLOUDREPO_REPOSITORY} \ -Dusername=${CLOUDREPO_CREDENTIALS_USR} \ -Dpassword=${CLOUDREPO_CREDENTIALS_PSW} ''' } } }}GitHub Actions Updates
Complete workflow example:
name: Build and Deploy to CloudRepo
on: push: branches: [main, develop] pull_request: branches: [main]
jobs: build: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v3
- name: Set up JDK 11 uses: actions/setup-java@v3 with: java-version: '11' distribution: 'temurin'
- name: Configure Maven for CloudRepo run: | mkdir -p ~/.m2 cat > ~/.m2/settings.xml << EOF <settings> <servers> <server> <id>cloudrepo-releases</id> <username>${{ secrets.CLOUDREPO_USERNAME }}</username> <password>${{ secrets.CLOUDREPO_TOKEN }}</password> </server> <server> <id>cloudrepo-snapshots</id> <username>${{ secrets.CLOUDREPO_USERNAME }}</username> <password>${{ secrets.CLOUDREPO_TOKEN }}</password> </server> </servers> <profiles> <profile> <id>cloudrepo</id> <repositories> <repository> <id>cloudrepo-public</id> <url>https://YOUR_ORG.cloudrepo.io/repository/maven-public</url> </repository> </repositories> </profile> </profiles> <activeProfiles> <activeProfile>cloudrepo</activeProfile> </activeProfiles> </settings> EOF
- name: Build with Maven run: mvn clean package
- name: Deploy to CloudRepo if: github.ref == 'refs/heads/main' run: mvn deployGitLab CI Modifications
variables: MAVEN_OPTS: '-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository'
cache: paths: - .m2/repository
before_script: - apt-get update -qq && apt-get install -y maven - | cat > ~/.m2/settings.xml << EOF <settings> <servers> <server> <id>cloudrepo</id> <username>${CLOUDREPO_USERNAME}</username> <password>${CLOUDREPO_TOKEN}</password> </server> </servers> <mirrors> <mirror> <id>cloudrepo</id> <mirrorOf>*</mirrorOf> <url>https://YOUR_ORG.cloudrepo.io/repository/maven-public</url> </mirror> </mirrors> </settings> EOF
build: stage: build script: - mvn clean compile
test: stage: test script: - mvn test
deploy: stage: deploy script: - mvn deploy only: - main - tagsCommon Challenges and Solutions
Challenge 1: Large Artifact Migration
Problem: Migrating terabytes of artifacts takes too long.
Solution: Use CloudRepo’s bulk import service:
# Contact CloudRepo support for bulk import# They provide:# 1. S3 bucket for direct upload# 2. Parallel processing of your artifacts# 3. Verification reports
# Or use parallel migration scriptfind /nexus-data/blobs -type f -name "*.jar" | \ parallel -j 10 ./migrate-artifact.sh {}Challenge 2: Custom Nexus Plugins
Problem: Using custom Nexus plugins with no CloudRepo equivalent.
Solutions:
- Webhook Integration: Replace plugins with CloudRepo webhooks
- API Automation: Use CloudRepo’s REST API for custom workflows
- CI/CD Pipeline: Move logic from Nexus plugins to CI/CD
// Example: Replace Nexus cleanup plugin with CloudRepo APIconst cleanupOldArtifacts = async () => { const response = await fetch('https://api.cloudrepo.io/artifacts', { headers: { Authorization: `Bearer ${TOKEN}` }, });
const artifacts = await response.json(); const thirtyDaysAgo = Date.now() - 30 * 24 * 60 * 60 * 1000;
for (const artifact of artifacts) { if (new Date(artifact.created).getTime() < thirtyDaysAgo) { await fetch(`https://api.cloudrepo.io/artifacts/${artifact.id}`, { method: 'DELETE', headers: { Authorization: `Bearer ${TOKEN}` }, }); } }};Challenge 3: Repository Cleanup Policies
Problem: Nexus cleanup policies need to be replicated.
Solution: CloudRepo retention policies:
{ "repository": "maven-snapshots", "retentionPolicy": { "maxAge": "30d", "maxCount": 10, "keepReleases": true }}Challenge 4: Access Control Differences
Problem: Complex LDAP/Active Directory integration in Nexus.
Solution: CloudRepo supports SAML SSO and API tokens:
# Generate API tokens for service accountscurl -X POST https://api.cloudrepo.io/tokens \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "ci-cd-token", "permissions": ["read", "write"], "repositories": ["maven-releases", "maven-snapshots"] }'Post-Migration Best Practices
Monitoring and Alerts
Set up comprehensive monitoring:
# CloudRepo monitoring endpointsmonitoring: health_check: https://YOUR_ORG.cloudrepo.io/health metrics: https://api.cloudrepo.io/metrics
alerts: - type: download_failures threshold: 5 window: 5m - type: upload_failures threshold: 3 window: 5m - type: storage_usage threshold: 80%Backup Strategies
CloudRepo provides automatic backups, but consider:
- Artifact versioning: Keep all versions by default
- Metadata exports: Regular exports of repository configurations
- Disaster recovery plan: Document recovery procedures
# Export repository metadatacurl -X GET https://api.cloudrepo.io/repositories/export \ -H "Authorization: Bearer TOKEN" \ -o repository-backup-$(date +%Y%m%d).jsonPerformance Optimization
Optimize CloudRepo usage:
<!-- Use CloudRepo's CDN for better performance --><repository> <id>cloudrepo-cdn</id> <url>https://cdn.cloudrepo.io/YOUR_ORG/maven-public</url></repository>Cost Tracking
Monitor and optimize costs:
import requestsfrom datetime import datetime, timedelta
def get_usage_report(): """Generate monthly usage report""" response = requests.get( 'https://api.cloudrepo.io/usage', headers={'Authorization': f'Bearer {TOKEN}'}, params={ 'from': (datetime.now() - timedelta(days=30)).isoformat(), 'to': datetime.now().isoformat() } )
usage = response.json()
# Compare with Nexus costs nexus_monthly_cost = 3800 # Your previous Nexus costs cloudrepo_monthly_cost = usage['total_cost'] savings = nexus_monthly_cost - cloudrepo_monthly_cost savings_percentage = (savings / nexus_monthly_cost) * 100
print(f"Monthly Savings: ${savings:,.2f} ({savings_percentage:.1f}%)")
return usageRollback Plan
While CloudRepo migrations are typically smooth, having a rollback plan provides peace of mind:
1. Keep Nexus in Read-Only Mode
# Set Nexus to read-onlycurl -X PUT https://nexus.example.com/service/rest/v1/security/readonly \ -H "Authorization: Basic $(echo -n admin:password | base64)" \ -H "Content-Type: application/json" \ -d '{"enabled": true}'2. Dual-Publishing Strategy
During transition, publish to both repositories:
// Dual publishing in Jenkinsstage('Deploy') { parallel { stage('Deploy to CloudRepo') { steps { sh 'mvn deploy -P cloudrepo' } } stage('Deploy to Nexus') { when { expression { params.DUAL_PUBLISH == true } } steps { sh 'mvn deploy -P nexus' } } }}3. Emergency Rollback Procedure
If rollback is needed:
- Stop new deployments to CloudRepo
- Update all configurations back to Nexus URLs
- Remove Nexus read-only mode
- Sync any artifacts deployed only to CloudRepo back to Nexus
- Document issues for CloudRepo support team
CloudRepo Support: Our migration team is available to assist with any challenges. Contact support@cloudrepo.io for immediate help.
Cost Comparison Calculator
Calculate your potential savings:
Small Team (5 developers, 50GB storage)
| Cost Component | Nexus (Self-Hosted) | CloudRepo | Savings |
|---|---|---|---|
| Infrastructure | $500/month | $0 | $500 |
| Storage | $100/month | $0 | $100 |
| Bandwidth | $200/month | $0 | $200 |
| Maintenance (4hr/month @ $150/hr) | $600/month | $0 | $600 |
| Support Contract | $300/month | Included | $300 |
| Total Monthly | $1,700 | $79 | $1,621 (95%) |
| Total Annual | $20,400 | $948 | $19,452 |
Medium Team (25 developers, 500GB storage)
| Cost Component | Nexus (Self-Hosted) | CloudRepo | Savings |
|---|---|---|---|
| Infrastructure (HA setup) | $1,500/month | $0 | $1,500 |
| Storage | $300/month | $0 | $300 |
| Bandwidth | $500/month | $0 | $500 |
| Maintenance (10hr/month @ $150/hr) | $1,500/month | $0 | $1,500 |
| Support Contract | $800/month | Included | $800 |
| Total Monthly | $4,600 | $299 | $4,301 (93%) |
| Total Annual | $55,200 | $3,588 | $51,612 |
Enterprise Team (100+ developers, 5TB storage)
| Cost Component | Nexus Pro | CloudRepo | Savings |
|---|---|---|---|
| License | $3,000/month | $0 | $3,000 |
| Infrastructure (Enterprise HA) | $3,500/month | $0 | $3,500 |
| Storage & Backup | $1,000/month | $0 | $1,000 |
| Bandwidth | $2,000/month | $0 | $2,000 |
| DevOps Team (0.5 FTE) | $5,000/month | $0 | $5,000 |
| Enterprise Support | $2,000/month | Included | $2,000 |
| Total Monthly | $16,500 | $999 | $15,501 (94%) |
| Total Annual | $198,000 | $11,988 | $186,012 |
ROI Calculator: Most organizations see positive ROI within the first month after migration. Calculate your specific savings at cloudrepo.io/pricing.
Conclusion: Make the Switch with Confidence
Migrating from Sonatype Nexus to CloudRepo is a strategic decision that delivers immediate cost savings and long-term operational benefits. With this comprehensive guide, you have everything needed for a successful migration:
Quick Wins After Migration
- Day 1: 90%+ cost reduction realized immediately
- Week 1: Developers report faster artifact downloads
- Month 1: Zero infrastructure maintenance performed
- Month 3: First avoided Nexus upgrade cycle
- Year 1: Saved enough to fund additional development resources
Next Steps
- Start Free Trial: Sign up at cloudrepo.io/signup
- Run Cost Analysis: Calculate your specific savings
- Plan Migration: Use this guide to create your migration plan
- Get Support: Contact support@cloudrepo.io for migration assistance
Why CloudRepo Wins
- No Infrastructure: Eliminate servers, storage, and maintenance forever
- Predictable Costs: Simple pricing with no hidden fees
- Enterprise Features: Everything you need, nothing you don’t
- Superior Support: Included with every plan, no expensive contracts
- Global Performance: CDN-backed delivery beats any single Nexus server
Ready to Save 90%? Start your free CloudRepo trial today. Most teams complete migration in under a week and see immediate cost savings. No credit card required.
Questions about migrating from Nexus to CloudRepo? Our migration experts are standing by to help. Email support@cloudrepo.io or start a chat at cloudrepo.io.
Ready to save 90% on your repository hosting?
Join thousands of teams who've switched to CloudRepo for better pricing and features.
Related Articles
Bitbucket Pipelines with Maven: Complete Guide
A comprehensive walkthrough for setting up Bitbucket Pipelines to push and pull from Private Maven Repositories
JFrog Artifactory to CloudRepo Migration Guide
Step-by-step guide to migrate from JFrog Artifactory to CloudRepo. Escape complex licensing, eliminate egress fees, and reduce costs by 90%+ with our comprehensive migration playbook.
How to Use CloudRepo with GitHub Actions
Complete guide to integrating CloudRepo with GitHub Actions for Maven, Gradle, and Python builds. Includes working examples and CI/CD best practices.