diff --git a/components.d.ts b/components.d.ts
index fabbe793..e31119b3 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -12,6 +12,7 @@ declare module '@vue/runtime-core' {
     '404.page': typeof import('./src/pages/404.page.vue')['default']
     About: typeof import('./src/pages/About.vue')['default']
     App: typeof import('./src/App.vue')['default']
+    AsciiTextDrawer: typeof import('./src/tools/ascii-text-drawer/ascii-text-drawer.vue')['default']
     'Base.layout': typeof import('./src/layouts/base.layout.vue')['default']
     Base64FileConverter: typeof import('./src/tools/base64-file-converter/base64-file-converter.vue')['default']
     Base64StringConverter: typeof import('./src/tools/base64-string-converter/base64-string-converter.vue')['default']
@@ -88,28 +89,17 @@ declare module '@vue/runtime-core' {
     HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
     IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
     'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
-    'IconMdi:contentCopy': typeof import('~icons/mdi/content-copy')['default']
     'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
-    IconMdiArrowDown: typeof import('~icons/mdi/arrow-down')['default']
-    IconMdiArrowRightBottom: typeof import('~icons/mdi/arrow-right-bottom')['default']
-    IconMdiCamera: typeof import('~icons/mdi/camera')['default']
     IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
     IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
     IconMdiClose: typeof import('~icons/mdi/close')['default']
     IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
-    IconMdiDeleteOutline: typeof import('~icons/mdi/delete-outline')['default']
-    IconMdiDownload: typeof import('~icons/mdi/download')['default']
     IconMdiEye: typeof import('~icons/mdi/eye')['default']
     IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
     IconMdiHeart: typeof import('~icons/mdi/heart')['default']
-    IconMdiPause: typeof import('~icons/mdi/pause')['default']
-    IconMdiPlay: typeof import('~icons/mdi/play')['default']
-    IconMdiRecord: typeof import('~icons/mdi/record')['default']
-    IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
     IconMdiSearch: typeof import('~icons/mdi/search')['default']
     IconMdiTranslate: typeof import('~icons/mdi/translate')['default']
     IconMdiTriangleDown: typeof import('~icons/mdi/triangle-down')['default']
-    IconMdiVideo: typeof import('~icons/mdi/video')['default']
     InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
     IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
     Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
@@ -136,39 +126,25 @@ declare module '@vue/runtime-core' {
     MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
     MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
     MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
-    NAlert: typeof import('naive-ui')['NAlert']
     NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
-    NCheckbox: typeof import('naive-ui')['NCheckbox']
     NCode: typeof import('naive-ui')['NCode']
     NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
-    NColorPicker: typeof import('naive-ui')['NColorPicker']
     NConfigProvider: typeof import('naive-ui')['NConfigProvider']
-    NDatePicker: typeof import('naive-ui')['NDatePicker']
     NDivider: typeof import('naive-ui')['NDivider']
-    NDynamicInput: typeof import('naive-ui')['NDynamicInput']
     NEllipsis: typeof import('naive-ui')['NEllipsis']
-    NForm: typeof import('naive-ui')['NForm']
     NFormItem: typeof import('naive-ui')['NFormItem']
     NGi: typeof import('naive-ui')['NGi']
     NGrid: typeof import('naive-ui')['NGrid']
     NH1: typeof import('naive-ui')['NH1']
-    NH2: typeof import('naive-ui')['NH2']
     NH3: typeof import('naive-ui')['NH3']
     NIcon: typeof import('naive-ui')['NIcon']
-    NImage: typeof import('naive-ui')['NImage']
-    NInputGroup: typeof import('naive-ui')['NInputGroup']
-    NInputGroupLabel: typeof import('naive-ui')['NInputGroupLabel']
     NInputNumber: typeof import('naive-ui')['NInputNumber']
+    NLabel: typeof import('naive-ui')['NLabel']
     NLayout: typeof import('naive-ui')['NLayout']
     NLayoutSider: typeof import('naive-ui')['NLayoutSider']
     NMenu: typeof import('naive-ui')['NMenu']
-    NProgress: typeof import('naive-ui')['NProgress']
     NScrollbar: typeof import('naive-ui')['NScrollbar']
-    NSlider: typeof import('naive-ui')['NSlider']
-    NStatistic: typeof import('naive-ui')['NStatistic']
-    NSwitch: typeof import('naive-ui')['NSwitch']
-    NTable: typeof import('naive-ui')['NTable']
-    NTag: typeof import('naive-ui')['NTag']
+    NSpin: typeof import('naive-ui')['NSpin']
     NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
     OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
     PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
diff --git a/package.json b/package.json
index 304bb636..a9be06da 100644
--- a/package.json
+++ b/package.json
@@ -41,6 +41,7 @@
     "@tiptap/pm": "2.1.6",
     "@tiptap/starter-kit": "2.1.6",
     "@tiptap/vue-3": "2.0.3",
+    "@types/figlet": "^1.5.8",
     "@vicons/material": "^0.12.0",
     "@vicons/tabler": "^0.12.0",
     "@vueuse/core": "^10.3.0",
@@ -58,6 +59,7 @@
     "date-fns": "^2.29.3",
     "dompurify": "^3.0.6",
     "emojilib": "^3.0.10",
+    "figlet": "^1.7.0",
     "figue": "^1.2.0",
     "fuse.js": "^6.6.2",
     "highlight.js": "^11.7.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 219c4d0b..def705a2 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -23,6 +23,9 @@ dependencies:
   '@tiptap/vue-3':
     specifier: 2.0.3
     version: 2.0.3(@tiptap/core@2.1.12)(@tiptap/pm@2.1.6)(vue@3.3.4)
+  '@types/figlet':
+    specifier: ^1.5.8
+    version: 1.5.8
   '@vicons/material':
     specifier: ^0.12.0
     version: 0.12.0
@@ -74,6 +77,9 @@ dependencies:
   emojilib:
     specifier: ^3.0.10
     version: 3.0.10
+  figlet:
+    specifier: ^1.7.0
+    version: 1.7.0
   figue:
     specifier: ^1.2.0
     version: 1.2.0
@@ -2905,6 +2911,10 @@ packages:
   /@types/estree@1.0.0:
     resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==}
 
+  /@types/figlet@1.5.8:
+    resolution: {integrity: sha512-G22AUvy4Tl95XLE7jmUM8s8mKcoz+Hr+Xm9W90gJsppJq9f9tHvOGkrpn4gRX0q/cLtBdNkWtWCKDg2UDZoZvQ==}
+    dev: false
+
   /@types/fs-extra@11.0.1:
     resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==}
     dependencies:
@@ -5598,6 +5608,12 @@ packages:
       web-streams-polyfill: 3.2.1
     dev: true
 
+  /figlet@1.7.0:
+    resolution: {integrity: sha512-gO8l3wvqo0V7wEFLXPbkX83b7MVjRrk1oRLfYlZXol8nEpb/ON9pcKLI4qpBv5YtOTfrINtqb7b40iYY2FTWFg==}
+    engines: {node: '>= 0.4.0'}
+    hasBin: true
+    dev: false
+
   /figue@1.2.0:
     resolution: {integrity: sha512-CXKr12kiNWjKtUK3X+YHeXKepn80s9Rg6pgZXoLQYEybgwaGJ9uGW4DrBrVK30ZWZf1mcvTbXF56AcovG7gLVw==}
     dependencies:
diff --git a/src/tools/ascii-text-drawer/ascii-text-drawer.vue b/src/tools/ascii-text-drawer/ascii-text-drawer.vue
new file mode 100644
index 00000000..9a6520a4
--- /dev/null
+++ b/src/tools/ascii-text-drawer/ascii-text-drawer.vue
@@ -0,0 +1,93 @@
+
+
+
+  
+    
+
+    
+
+    
+      
+        
+      
+      
+        
+          
+        
+      
+    
+
+    
+
+    
+      
+      Loading font...
+    
+
+    
+      Current settings resulted in error.
+    
+
+    
+      
+    
+  
+
diff --git a/src/tools/ascii-text-drawer/index.ts b/src/tools/ascii-text-drawer/index.ts
new file mode 100644
index 00000000..cc1ba86c
--- /dev/null
+++ b/src/tools/ascii-text-drawer/index.ts
@@ -0,0 +1,12 @@
+import { Artboard } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+  name: 'ASCII Art Text Generator',
+  path: '/ascii-text-drawer',
+  description: 'Create ASCII art text with many fonts and styles.',
+  keywords: ['ascii', 'asciiart', 'text', 'drawer'],
+  component: () => import('./ascii-text-drawer.vue'),
+  icon: Artboard,
+  createdAt: new Date('2024-03-03'),
+});
diff --git a/src/tools/index.ts b/src/tools/index.ts
index 7c630ecc..d570f66d 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -1,8 +1,12 @@
 import { tool as base64FileConverter } from './base64-file-converter';
 import { tool as base64StringConverter } from './base64-string-converter';
 import { tool as basicAuthGenerator } from './basic-auth-generator';
+
+import { tool as asciiTextDrawer } from './ascii-text-drawer';
+
 import { tool as textToUnicode } from './text-to-unicode';
 import { tool as ansibleVaultCryptDecrypt } from './ansible-vault-crypt-decrypt';
+import { tool as safelinkDecoder } from './safelink-decoder';
 import { tool as pdfSignatureChecker } from './pdf-signature-checker';
 import { tool as numeronymGenerator } from './numeronym-generator';
 import { tool as macAddressGenerator } from './mac-address-generator';
@@ -137,6 +141,7 @@ export const toolsByCategory: ToolCategory[] = [
       userAgentParser,
       httpStatusCodes,
       jsonDiff,
+      safelinkDecoder,
     ],
   },
   {
@@ -173,7 +178,15 @@ export const toolsByCategory: ToolCategory[] = [
   },
   {
     name: 'Text',
-    components: [loremIpsumGenerator, textStatistics, emojiPicker, stringObfuscator, textDiff, numeronymGenerator],
+    components: [
+      loremIpsumGenerator,
+      textStatistics,
+      emojiPicker,
+      stringObfuscator,
+      textDiff,
+      numeronymGenerator,
+      asciiTextDrawer,
+    ],
   },
   {
     name: 'Data',
diff --git a/src/tools/safelink-decoder/index.ts b/src/tools/safelink-decoder/index.ts
new file mode 100644
index 00000000..ef865108
--- /dev/null
+++ b/src/tools/safelink-decoder/index.ts
@@ -0,0 +1,12 @@
+import { Mailbox } from '@vicons/tabler';
+import { defineTool } from '../tool';
+
+export const tool = defineTool({
+  name: 'Outlook Safelink decoder',
+  path: '/safelink-decoder',
+  description: 'Decode Outlook SafeLink links',
+  keywords: ['outlook', 'safelink', 'decoder'],
+  component: () => import('./safelink-decoder.vue'),
+  icon: Mailbox,
+  createdAt: new Date('2024-03-11'),
+});
diff --git a/src/tools/safelink-decoder/safelink-decoder.service.test.ts b/src/tools/safelink-decoder/safelink-decoder.service.test.ts
new file mode 100644
index 00000000..b601f01e
--- /dev/null
+++ b/src/tools/safelink-decoder/safelink-decoder.service.test.ts
@@ -0,0 +1,21 @@
+import { describe, expect, it } from 'vitest';
+import { decodeSafeLinksURL } from './safelink-decoder.service';
+
+describe('safelink-decoder', () => {
+  describe('decodeSafeLinksURL', () => {
+    describe('decode outlook safelink urls', () => {
+      it('should decode basic safelink urls', () => {
+        expect(decodeSafeLinksURL('https://aus01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.google.com%2Fsearch%3Fq%3Dsafelink%26rlz%3D1&data=05%7C02%7C%7C1ed07253975b46da1d1508dc3443752a%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C638442711583216725%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=%2BQY0HBnnxfI7pzZoxzlhZdDvYu80LwQB0zUUjrffVnk%3D&reserved=0'))
+          .toBe('https://www.google.com/search?q=safelink&rlz=1');
+      });
+      it('should decode encoded safelink urls', () => {
+        expect(decodeSafeLinksURL('https://aus01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.google.com%2Fsearch%3Fq%3Dsafelink%26rlz%3D1&data=05%7C02%7C%7C1ed07253975b46da1d1508dc3443752a%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C638442711583216725%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C0%7C%7C%7C&sdata=%2BQY0HBnnxfI7pzZoxzlhZdDvYu80LwQB0zUUjrffVnk%3D&reserved=0'))
+          .toBe('https://www.google.com/search?q=safelink&rlz=1');
+      });
+      it('throw on not outlook safelink urls', () => {
+        expect(() => decodeSafeLinksURL('https://google.com'))
+          .toThrow('Invalid SafeLinks URL provided');
+      });
+    });
+  });
+});
diff --git a/src/tools/safelink-decoder/safelink-decoder.service.ts b/src/tools/safelink-decoder/safelink-decoder.service.ts
new file mode 100644
index 00000000..96be00ab
--- /dev/null
+++ b/src/tools/safelink-decoder/safelink-decoder.service.ts
@@ -0,0 +1,7 @@
+export function decodeSafeLinksURL(safeLinksUrl: string) {
+  if (!safeLinksUrl.match(/\.safelinks\.protection\.outlook\.com/)) {
+    throw new Error('Invalid SafeLinks URL provided');
+  }
+
+  return new URL(safeLinksUrl).searchParams.get('url');
+}
diff --git a/src/tools/safelink-decoder/safelink-decoder.vue b/src/tools/safelink-decoder/safelink-decoder.vue
new file mode 100644
index 00000000..01337eb2
--- /dev/null
+++ b/src/tools/safelink-decoder/safelink-decoder.vue
@@ -0,0 +1,32 @@
+
+
+
+  
+    
+
+    
+
+    
+      
+    
+  
+