search-algoritm 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ ---
5
+
6
+ ## [1.0.1] - 2025-12-01
7
+ - Bumped version due to NPM error.
8
+
9
+ ## [1.0.0] - 2025-12-01
10
+
11
+ ### Added
12
+ - Initial release of **search-algoritm** npm package.
13
+ - Node.js and browser usage examples.
14
+ - Example files included in `Example Files` folder.
15
+ - Basic fuzzy search algorithm supporting `title` and `description` fields.
16
+ - **Levenshtein distance support** for fuzzy matching.
17
+ - README.md with installation instructions and usage examples.
18
+ - License file (MIT).
@@ -0,0 +1,6 @@
1
+ [
2
+ { "title": "Apple", "description": "A juicy fruit" },
3
+ { "title": "Banana", "description": "Yellow and sweet" },
4
+ { "title": "Orange", "description": "Citrus fruit with vitamin C" },
5
+ { "title": "Grapes", "description": "Small sweet fruits" }
6
+ ]
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Search Example</title>
7
+ <link rel="stylesheet" href="./style.css">
8
+ </head>
9
+ <body>
10
+
11
+ <div class="page-wrapper">
12
+ <div class="search-wrapper">
13
+ <input type="text" id="searchInput" class="search-input" placeholder="Search...">
14
+ <button id="searchBtn" class="search-btn">Search</button>
15
+ </div>
16
+ <ul id="searchResults" class="search-results"></ul>
17
+ </div>
18
+
19
+ <script type="module" src="./search.js"></script>
20
+ </body>
21
+ </html>
@@ -0,0 +1,3 @@
1
+ // Example backend IP
2
+ const backendIP = 'http://localhost:3000';
3
+ export default backendIP;
@@ -0,0 +1,55 @@
1
+ const express = require('express');
2
+ const path = require('path');
3
+ const fs = require('fs').promises;
4
+ const { searchAlgoritm } = require('search-algoritm');
5
+
6
+ const app = express();
7
+ const PORT = 3000;
8
+
9
+ // Directory containing the static frontend files
10
+ const staticPath = path.join(__dirname, 'Example files');
11
+ app.use(express.static(staticPath));
12
+
13
+ // Path to the JSON dataset used by the search engine
14
+ const dataPath = path.join(__dirname, 'data.json');
15
+
16
+ /**
17
+ * Reads and parses a JSON file asynchronously.
18
+ * If reading or parsing fails, an empty array is returned instead,
19
+ * ensuring the server remains stable.
20
+ */
21
+ const loadJson = async (filePath) => {
22
+ try {
23
+ const rawData = await fs.readFile(filePath, 'utf-8');
24
+ return JSON.parse(rawData);
25
+ } catch (err) {
26
+ console.error('[server] Error loading JSON file:', err);
27
+ return [];
28
+ }
29
+ };
30
+
31
+ /**
32
+ * Search API endpoint
33
+ * Example: GET /api/search?q=example
34
+ *
35
+ * Loads the JSON file for each request, runs the search algorithm,
36
+ * and returns the results along with the original query.
37
+ */
38
+ app.get('/api/search', async (req, res) => {
39
+ const query = req.query.q || "";
40
+
41
+ // Load data from disk
42
+ const searchData = await loadJson(dataPath);
43
+
44
+ // Execute search
45
+ const results = searchAlgoritm(query, searchData);
46
+
47
+ res.json({ query, results });
48
+ });
49
+
50
+ /**
51
+ * Start the Express server
52
+ */
53
+ app.listen(PORT, () => {
54
+ console.log(`Server running at http://localhost:${PORT}`);
55
+ });
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "example-files",
3
+ "version": "1.0.0",
4
+ "main": "search.js",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1",
7
+ "start": "node server.js"
8
+ },
9
+ "keywords": [],
10
+ "author": "",
11
+ "license": "ISC",
12
+ "description": ""
13
+ }
@@ -0,0 +1,54 @@
1
+ // Import the backend server URL from a separate module
2
+ import backendIP from './ip-adress.js';
3
+
4
+ // Initialize the search functionality
5
+ async function initSearch() {
6
+ // Get references to the input field, search button, and results container
7
+ const searchInput = document.getElementById('searchInput');
8
+ const searchBtn = document.getElementById('searchBtn');
9
+ const resultsList = document.getElementById('searchResults');
10
+
11
+ // Function to perform the search when called
12
+ async function performSearch() {
13
+ // Get the input value and remove extra spaces
14
+ const query = searchInput.value.trim();
15
+
16
+ // If the input is empty, show a message and stop
17
+ if (!query) {
18
+ resultsList.innerHTML = `<li class="no-result">Please enter a search term</li>`;
19
+ return;
20
+ }
21
+
22
+ try {
23
+ // Fetch search results from the backend API
24
+ const res = await fetch(`${backendIP}/api/search?q=${encodeURIComponent(query)}`);
25
+ // Parse the JSON response
26
+ const { results } = await res.json();
27
+
28
+ // Render results in the DOM
29
+ resultsList.innerHTML = results.length
30
+ ? results.map(item => `
31
+ <li class="result-item">
32
+ <strong>${item.title}</strong><br>
33
+ <span>${item.description}</span>
34
+ </li>
35
+ `).join('') // Join all results into a single string
36
+ : `<li class="no-result">No matches found</li>`; // Show message if no results
37
+ } catch (err) {
38
+ // Handle any errors from the fetch call
39
+ console.error('Error fetching search results:', err);
40
+ resultsList.innerHTML = `<li class="no-result">Could not fetch results</li>`;
41
+ }
42
+ }
43
+
44
+ // Trigger search when the user presses Enter in the input field
45
+ searchInput.addEventListener('keydown', e => {
46
+ if (e.key === 'Enter') performSearch();
47
+ });
48
+
49
+ // Trigger search when the user clicks the search button
50
+ searchBtn.addEventListener('click', performSearch);
51
+ }
52
+
53
+ // Call the function to initialize search when the script loads
54
+ initSearch();
@@ -0,0 +1,65 @@
1
+ // server.js
2
+ const express = require('express');
3
+ const path = require('path');
4
+ const fs = require('fs').promises;
5
+ const { searchAlgoritm } = require('search-algoritm');
6
+
7
+ const app = express();
8
+ const PORT = 3000;
9
+
10
+ // Path to the JSON file containing searchable data
11
+ const dataPath = path.join(__dirname, 'data.json');
12
+
13
+ // In-memory cache for search data
14
+ let searchData = [];
15
+
16
+ /**
17
+ * Load the JSON file into memory.
18
+ * This reduces file I/O and makes searching faster.
19
+ */
20
+ const loadData = async () => {
21
+ try {
22
+ const rawData = await fs.readFile(dataPath, 'utf-8');
23
+ searchData = JSON.parse(rawData);
24
+ console.log(`[server] Loaded ${searchData.length} items into cache`);
25
+ } catch (err) {
26
+ console.error('[server] Failed to load data.json:', err);
27
+ }
28
+ };
29
+
30
+ // Load data on startup
31
+ loadData();
32
+
33
+ /**
34
+ * Optional:
35
+ * Automatically reload the cached data whenever the file changes.
36
+ * This ensures the server always uses the latest data without restarting.
37
+ */
38
+ fs.watchFile(dataPath, async () => {
39
+ console.log('[server] data.json changed — reloading cache...');
40
+ await loadData();
41
+ });
42
+
43
+ // Serve static frontend files
44
+ app.use(express.static(path.join(__dirname, 'Example files')));
45
+
46
+ /**
47
+ * Search API endpoint
48
+ * Example: GET /api/search?q=hello
49
+ */
50
+ app.get('/api/search', (req, res) => {
51
+ const query = (req.query.q || "").trim();
52
+
53
+ // Empty query → return an empty result set
54
+ if (!query) return res.json({ query, results: [] });
55
+
56
+ // Perform search on the cached list
57
+ const results = searchAlgoritm(query, searchData);
58
+
59
+ res.json({ query, results });
60
+ });
61
+
62
+ // Start the server
63
+ app.listen(PORT, () => {
64
+ console.log(`Server running at http://localhost:${PORT}`);
65
+ });
@@ -0,0 +1,56 @@
1
+ body {
2
+ font-family: Arial, sans-serif;
3
+ background: #0f0f0f;
4
+ color: #e4e4e4;
5
+ display: flex;
6
+ justify-content: center;
7
+ align-items: center;
8
+ min-height: 100vh;
9
+ margin: 0;
10
+ }
11
+
12
+ .page-wrapper {
13
+ max-width: 500px;
14
+ width: 100%;
15
+ }
16
+
17
+ .search-wrapper {
18
+ display: flex;
19
+ gap: 8px;
20
+ margin-bottom: 12px;
21
+ }
22
+
23
+ .search-input {
24
+ flex: 1;
25
+ padding: 10px;
26
+ border-radius: 6px;
27
+ border: 1px solid #444;
28
+ background: #1b1b1b;
29
+ color: #e6e6e6;
30
+ }
31
+
32
+ .search-btn {
33
+ padding: 10px 16px;
34
+ border: none;
35
+ border-radius: 6px;
36
+ background: #3b82f6;
37
+ color: white;
38
+ cursor: pointer;
39
+ }
40
+
41
+ .search-results {
42
+ list-style: none;
43
+ padding: 0;
44
+ }
45
+
46
+ .result-item {
47
+ padding: 10px;
48
+ background: #181818;
49
+ margin-bottom: 6px;
50
+ border-radius: 6px;
51
+ }
52
+
53
+ .no-result {
54
+ color: #f87171;
55
+ padding: 10px;
56
+ }
package/LICENSE ADDED
@@ -0,0 +1,14 @@
1
+ Copyright (c) 2025 Felix Lind
2
+
3
+ All rights reserved.
4
+
5
+ Permission is granted to install, use, and execute this software as provided via npm or other official distribution channels. This includes use in personal, internal, or commercial projects as part of a larger application or website.
6
+
7
+ You MAY NOT:
8
+ - Sell, redistribute, or sublicense this software as a standalone product.
9
+ - Modify and distribute modified versions of this software as a standalone product.
10
+ - Extract, copy, or otherwise distribute the source code outside of the intended installation/usage.
11
+
12
+ This software is provided "AS IS", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, or non-infringement. In no event shall the author be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or its use.
13
+
14
+ By installing or using this software, you agree to comply with the above restrictions.
package/README.md ADDED
@@ -0,0 +1,201 @@
1
+ ````markdown
2
+ # search-algoritm
3
+
4
+ ![npm version](https://img.shields.io/npm/v/search-algoritm.svg)
5
+ ![npm downloads](https://img.shields.io/npm/dm/search-algoritm.svg)
6
+ ![license](https://img.shields.io/npm/l/search-algoritm.svg)
7
+ [![GitHub Repository](https://img.shields.io/badge/GitHub-Repository-blue?logo=github)](https://github.com/FelixLind1/SearchAlgoritm)
8
+
9
+ A lightweight Node.js library for **fuzzy searching** arrays of objects.
10
+ It calculates relevance scores based on how well a query matches the `title` and `description` of each item.
11
+
12
+ **Features:**
13
+
14
+ - Fuzzy matching using **Levenshtein distance**
15
+ - **Accent-insensitive** searches (`é → e`)
16
+ - Token-based word matching for partial or multi-word queries
17
+ - Weighted scoring: title matches are more important than description
18
+ - Stopword filtering for more relevant results
19
+
20
+ ---
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install search-algoritm
26
+ ````
27
+
28
+ ---
29
+
30
+ ## Node.js Usage (Server-side)
31
+
32
+ This library supports **two server setups** depending on your dataset size and update frequency:
33
+
34
+ 1. **Cached JSON Server** – loads JSON into memory once, reloads if the file changes (fast for large datasets).
35
+ 2. **Dynamic JSON Server** – reads JSON from disk on each request (simple, slower for large datasets).
36
+
37
+ ---
38
+
39
+ ### 1. Cached JSON Server (`server.js`)
40
+
41
+ ```js
42
+ const express = require('express');
43
+ const path = require('path');
44
+ const fs = require('fs').promises;
45
+ const { searchAlgoritm } = require('search-algoritm');
46
+
47
+ const app = express();
48
+ const PORT = 3000;
49
+ const dataPath = path.join(__dirname, 'data.json');
50
+
51
+ let searchData = [];
52
+
53
+ // Load data into memory
54
+ const loadData = async () => {
55
+ try {
56
+ const rawData = await fs.readFile(dataPath, 'utf-8');
57
+ searchData = JSON.parse(rawData);
58
+ console.log(`[server] Loaded ${searchData.length} items`);
59
+ } catch (err) {
60
+ console.error('[server] Failed to load data.json:', err);
61
+ }
62
+ };
63
+
64
+ loadData();
65
+
66
+ // Reload cache if file changes
67
+ fs.watchFile(dataPath, async () => {
68
+ console.log('[server] data.json changed, reloading cache...');
69
+ await loadData();
70
+ });
71
+
72
+ app.use(express.static(path.join(__dirname, 'Example files')));
73
+
74
+ app.get('/api/search', async (req, res) => {
75
+ const query = (req.query.q || "").trim();
76
+ if (!query) return res.json({ query, results: [] });
77
+
78
+ const results = searchAlgoritm(query, searchData);
79
+ res.json({ query, results });
80
+ });
81
+
82
+ app.listen(PORT, () => {
83
+ console.log(`Server running on http://localhost:${PORT}`);
84
+ });
85
+ ```
86
+
87
+ ✅ Fast searches using in-memory cache. Ideal for **medium to large datasets** where performance matters.
88
+
89
+ ---
90
+
91
+ ### 2. Dynamic JSON Server (`json-server.js`)
92
+
93
+ ```js
94
+ const express = require('express');
95
+ const path = require('path');
96
+ const fs = require('fs').promises;
97
+ const { searchAlgoritm } = require('search-algoritm');
98
+
99
+ const app = express();
100
+ const PORT = 3000;
101
+
102
+ app.use(express.static(path.join(__dirname, 'Example files')));
103
+ const dataPath = path.join(__dirname, 'data.json');
104
+
105
+ const loadJson = async (filePath) => {
106
+ try {
107
+ const rawData = await fs.readFile(filePath, 'utf-8');
108
+ return JSON.parse(rawData);
109
+ } catch (err) {
110
+ console.error('Error reading JSON file:', err);
111
+ return [];
112
+ }
113
+ };
114
+
115
+ app.get('/api/search', async (req, res) => {
116
+ const query = req.query.q || "";
117
+ const searchData = await loadJson(dataPath);
118
+ const results = searchAlgoritm(query, searchData);
119
+ res.json({ query, results });
120
+ });
121
+
122
+ app.listen(PORT, () => {
123
+ console.log(`Server running on http://localhost:${PORT}`);
124
+ });
125
+ ```
126
+
127
+ ✅ Reads JSON on each request. Best for **small datasets** or when data changes frequently.
128
+
129
+ ---
130
+
131
+ ## Best Practices
132
+
133
+ | Server Type | Pros | Cons | When to Use |
134
+ | ------------ | ------------------------------- | ---------------------------------------------- | ------------------------------------------- |
135
+ | Cached JSON | Fast searches, reduces disk I/O | Uses more memory, needs cache reload on change | Medium to large datasets, frequent searches |
136
+ | Dynamic JSON | Always fresh data, simple setup | Slower for large datasets | Small datasets or frequently changing data |
137
+
138
+ **Tip:** For production with large datasets, use the **cached server**. For prototypes or rapidly changing content, use the **dynamic server**.
139
+
140
+ ---
141
+
142
+ ## Frontend Usage (Browser)
143
+
144
+ Always fetch search results from the server.
145
+
146
+ ### `ip-adress.js`
147
+
148
+ ```js
149
+ const backendIP = 'http://localhost:3000';
150
+ export default backendIP;
151
+ ```
152
+
153
+ ### `search.js`
154
+
155
+ ```js
156
+ import backendIP from './ip-adress.js';
157
+
158
+ async function initSearch() {
159
+ const searchInput = document.getElementById('searchInput');
160
+ const searchBtn = document.getElementById('searchBtn');
161
+ const resultsList = document.getElementById('searchResults');
162
+
163
+ async function performSearch() {
164
+ const query = searchInput.value.trim();
165
+ if (!query) {
166
+ resultsList.innerHTML = `<li class="no-result">Please enter a search term</li>`;
167
+ return;
168
+ }
169
+
170
+ try {
171
+ const res = await fetch(`${backendIP}/api/search?q=${encodeURIComponent(query)}`);
172
+ const { results } = await res.json();
173
+
174
+ resultsList.innerHTML = results.length
175
+ ? results.map(item => `
176
+ <li class="result-item">
177
+ <strong>${item.title}</strong><br>
178
+ <span>${item.description}</span>
179
+ </li>
180
+ `).join('')
181
+ : `<li class="no-result">No matches found</li>`;
182
+ } catch (err) {
183
+ console.error('Error fetching search results:', err);
184
+ resultsList.innerHTML = `<li class="no-result">Could not fetch results</li>`;
185
+ }
186
+ }
187
+
188
+ searchInput.addEventListener('keydown', e => { if (e.key === 'Enter') performSearch(); });
189
+ searchBtn.addEventListener('click', performSearch);
190
+ }
191
+
192
+ initSearch();
193
+ ```
194
+
195
+ ---
196
+
197
+ ## License
198
+
199
+ MIT
200
+
201
+ **Made by [Felix Lind](https://github.com/FelixLind1)**
package/index.js ADDED
@@ -0,0 +1,4 @@
1
+ // search-algoritm/index.js
2
+ const { searchAlgoritm } = require('./src/searchAlgoritm');
3
+
4
+ module.exports = { searchAlgoritm };
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "search-algoritm",
3
+ "version": "1.0.1",
4
+ "description": "Simple and lightweight fuzzy search algoritm for titles and descriptions.",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "keywords": [
10
+ "search",
11
+ "fuzzy",
12
+ "algoritm",
13
+ "filter",
14
+ "javascript",
15
+ "node"
16
+ ],
17
+ "author": "Felix Lind",
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/FelixLind1/SearchAlgoritm.git"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/FelixLind1/SearchAlgoritm/issues"
25
+ },
26
+ "homepage": "https://github.com/FelixLind1/SearchAlgoritm/blob/main/README.md"
27
+ }
@@ -0,0 +1,140 @@
1
+ // searchAlgoritm.js
2
+ console.log('[searchAlgoritm] 🔍 Module loaded');
3
+
4
+ /**
5
+ * Normalize text: lowercase, remove accents, trim, remove simple plurals
6
+ * @param {string} str
7
+ * @returns {string}
8
+ */
9
+ const normalize = (str) =>
10
+ str
11
+ .toLowerCase()
12
+ .normalize('NFD') // Normalize unicode (accents)
13
+ .replace(/[\u0300-\u036f]/g, '') // Remove diacritics (é → e)
14
+ .replace(/s$/, '') // Remove trailing 's' (simple plural)
15
+ .trim();
16
+
17
+ /**
18
+ * Levenshtein distance (edit distance)
19
+ * Measures how many edits are needed to transform string a into b
20
+ * @param {string} a
21
+ * @param {string} b
22
+ * @returns {number}
23
+ */
24
+ const levenshtein = (a, b) => {
25
+ if (a === b) return 0;
26
+ if (!a) return b.length;
27
+ if (!b) return a.length;
28
+
29
+ const matrix = Array.from({ length: b.length + 1 }, (_, i) => [i]);
30
+ for (let j = 0; j <= a.length; j++) matrix[0][j] = j;
31
+
32
+ for (let i = 1; i <= b.length; i++) {
33
+ for (let j = 1; j <= a.length; j++) {
34
+ matrix[i][j] = b[i - 1] === a[j - 1]
35
+ ? matrix[i - 1][j - 1]
36
+ : Math.min(
37
+ matrix[i - 1][j - 1] + 1, // substitution
38
+ matrix[i][j - 1] + 1, // insertion
39
+ matrix[i - 1][j] + 1 // deletion
40
+ );
41
+ }
42
+ }
43
+
44
+ return matrix[b.length][a.length];
45
+ };
46
+
47
+ /**
48
+ * Common stopwords to ignore during search
49
+ */
50
+ const stopWords = new Set([
51
+ 'and', 'the', 'of', 'a', 'i', 'in', 'on', 'for', 'with',
52
+ 'en', 'ett', 'och', 'från', 'med', 'på', 'för'
53
+ ]);
54
+
55
+ /**
56
+ * Tokenize a string into words, normalize, and remove stopwords
57
+ * @param {string} text
58
+ * @returns {Array<string>}
59
+ */
60
+ const tokenize = (text) =>
61
+ normalize(text)
62
+ .split(/\s+/)
63
+ .filter(word => word && !stopWords.has(word));
64
+
65
+ /**
66
+ * Compute fuzzy match score between a text and a query (0-100)
67
+ * @param {string} text
68
+ * @param {string} query
69
+ * @returns {number}
70
+ */
71
+ const matchScore = (text, query) => {
72
+ if (!text || !query) return 0;
73
+
74
+ const queryTokens = tokenize(query);
75
+ const textTokens = tokenize(text);
76
+ let score = 0;
77
+
78
+ // Compare each query token against all text tokens
79
+ for (const qWord of queryTokens) {
80
+ if (textTokens.includes(qWord)) {
81
+ score += 20; // Full match
82
+ } else {
83
+ // Fuzzy match via Levenshtein similarity
84
+ const bestSim = Math.max(...textTokens.map(tw => {
85
+ const dist = levenshtein(tw, qWord);
86
+ return (1 - dist / Math.max(tw.length, qWord.length)) * 100;
87
+ }));
88
+ if (bestSim > 50) score += bestSim / 2; // Half points for close match
89
+ }
90
+ }
91
+
92
+ // Extra points if any word in text starts with a query token
93
+ if (textTokens.some(tw => queryTokens.some(q => tw.startsWith(q)))) score += 10;
94
+
95
+ return Math.min(Math.round(score), 100);
96
+ };
97
+
98
+ /**
99
+ * Compute weighted score for an item (title is weighted higher than description)
100
+ * @param {object} item
101
+ * @param {string} query
102
+ * @returns {number}
103
+ */
104
+ const calculateItemScore = (item, query) => {
105
+ const title = item._lcTitle ?? normalize(item.title);
106
+ const desc = item._lcDesc ?? normalize(item.description);
107
+ return matchScore(title, query) * 3 + matchScore(desc, query);
108
+ };
109
+
110
+ /**
111
+ * Main search function
112
+ * @param {string} query
113
+ * @param {Array<object>} dataList
114
+ * @param {boolean} enableLog
115
+ * @returns {Array<object>} results sorted by relevance
116
+ */
117
+ const searchAlgoritm = (query, dataList, enableLog = false) => {
118
+ if (!query || !dataList) return [];
119
+
120
+ const normalizedQuery = normalize(query);
121
+
122
+ // Precompute normalized fields for faster scoring
123
+ dataList.forEach(item => {
124
+ item._lcTitle ??= normalize(item.title);
125
+ item._lcDesc ??= normalize(item.description);
126
+ });
127
+
128
+ const results = dataList
129
+ .map(item => ({ ...item, _score: calculateItemScore(item, normalizedQuery) }))
130
+ .filter(item => item._score > 0)
131
+ .sort((a, b) => b._score - a._score);
132
+
133
+ if (enableLog) {
134
+ console.log(`[searchAlgoritm] 🔎 Query: "${query}", results: ${results.length}`);
135
+ }
136
+
137
+ return results;
138
+ };
139
+
140
+ module.exports = { searchAlgoritm };