@operato/utils 8.0.0-beta.0 → 8.0.0-beta.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/package.json +2 -2
  3. package/.editorconfig +0 -29
  4. package/.storybook/main.js +0 -3
  5. package/.storybook/preview.js +0 -52
  6. package/.storybook/server.mjs +0 -8
  7. package/src/adjust-list-param.ts +0 -79
  8. package/src/async-lock.ts +0 -27
  9. package/src/clipboard.ts +0 -41
  10. package/src/closest-element.ts +0 -24
  11. package/src/context-path.ts +0 -42
  12. package/src/cookie.ts +0 -44
  13. package/src/decode-html.ts +0 -5
  14. package/src/detect-overflow.ts +0 -18
  15. package/src/encode-form-params.ts +0 -24
  16. package/src/file-drop-helper.ts +0 -62
  17. package/src/format.ts +0 -123
  18. package/src/fullscreen.ts +0 -82
  19. package/src/gesture-helper.ts +0 -147
  20. package/src/has-overflow.ts +0 -22
  21. package/src/index.ts +0 -25
  22. package/src/is-unvalued.ts +0 -10
  23. package/src/logger.ts +0 -32
  24. package/src/longpressable.ts +0 -101
  25. package/src/mixins/gesture-mixin.ts +0 -157
  26. package/src/mixins/index.ts +0 -2
  27. package/src/mixins/infinite-scrollable.ts +0 -67
  28. package/src/number-parser.ts +0 -24
  29. package/src/os.ts +0 -48
  30. package/src/parse-jwt.ts +0 -21
  31. package/src/password-pattern.ts +0 -63
  32. package/src/reactive-controllers/index.ts +0 -1
  33. package/src/reactive-controllers/tooltip-reactive-controller.ts +0 -88
  34. package/src/sleep.ts +0 -10
  35. package/src/stringify-bignum.ts +0 -35
  36. package/src/swipe-listener.ts +0 -290
  37. package/src/timecapsule/index.ts +0 -2
  38. package/src/timecapsule/snapshot-taker.ts +0 -105
  39. package/src/timecapsule/timecapsule.ts +0 -139
  40. package/tsconfig.json +0 -24
  41. package/web-dev-server.config.mjs +0 -27
  42. package/web-test-runner.config.mjs +0 -41
package/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [8.0.0-beta.1](https://github.com/hatiolab/operato/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2025-01-08)
7
+
8
+
9
+ ### :bug: Bug Fix
10
+
11
+ * missing .npmignore ([be05985](https://github.com/hatiolab/operato/commit/be05985abfae4af53501f718dd52932099f7fbcb))
12
+
13
+
14
+
6
15
  ## [8.0.0-beta.0](https://github.com/hatiolab/operato/compare/v8.0.0-alpha.56...v8.0.0-beta.0) (2025-01-07)
7
16
 
8
17
  **Note:** Version bump only for package @operato/utils
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@operato/utils",
3
3
  "description": "Webcomponent utils following open-wc recommendations",
4
4
  "author": "heartyoh",
5
- "version": "8.0.0-beta.0",
5
+ "version": "8.0.0-beta.1",
6
6
  "main": "dist/src/index.js",
7
7
  "module": "dist/src/index.js",
8
8
  "exports": {
@@ -127,5 +127,5 @@
127
127
  "dependencies": {
128
128
  "lodash-es": "^4.17.21"
129
129
  },
130
- "gitHead": "c4e9cc245659d050a9ffd66542083a6daad4bcb9"
130
+ "gitHead": "d5b28a2e9deb632c0dc80132f6a7196dd6fe4220"
131
131
  }
package/.editorconfig DELETED
@@ -1,29 +0,0 @@
1
- # EditorConfig helps developers define and maintain consistent
2
- # coding styles between different editors and IDEs
3
- # editorconfig.org
4
-
5
- root = true
6
-
7
-
8
- [*]
9
-
10
- # Change these settings to your own preference
11
- indent_style = space
12
- indent_size = 2
13
-
14
- # We recommend you to keep these unchanged
15
- end_of_line = lf
16
- charset = utf-8
17
- trim_trailing_whitespace = true
18
- insert_final_newline = true
19
-
20
- [*.md]
21
- trim_trailing_whitespace = false
22
-
23
- [*.json]
24
- indent_size = 2
25
-
26
- [*.{html,js,md}]
27
- block_comment_start = /**
28
- block_comment = *
29
- block_comment_end = */
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- stories: ['../dist/stories/**/*.stories.{js,md,mdx}'],
3
- };
@@ -1,52 +0,0 @@
1
- import { i18next } from '@operato/i18n'
2
-
3
- export const globalTypes = {
4
- locale: {
5
- name: 'Locale',
6
- description: 'Internationalization locale',
7
- toolbar: {
8
- icon: 'globe',
9
- items: [
10
- { value: 'en', right: '🇺🇸', title: 'English' },
11
- { value: 'ko', right: '🇰🇷', title: '한국어' },
12
- { value: 'zh', right: '🇨🇳', title: '中文' },
13
- { value: 'ja', right: '🇯🇵', title: '日本語' },
14
- { value: 'ms', right: '🇲🇾', title: 'Bahasa Melayu' }
15
- ],
16
- showName: true
17
- }
18
- },
19
- theme: {
20
- name: 'Theme',
21
- description: 'Global theme for components',
22
- toolbar: {
23
- icon: 'paintbrush',
24
- items: [
25
- { value: 'light', title: 'Light' },
26
- { value: 'dark', title: 'Dark' }
27
- ],
28
- showName: true
29
- }
30
- }
31
- }
32
-
33
- export const decorators = [
34
- (Story, context) => {
35
- const { locale, theme } = context.globals
36
-
37
- if (locale) {
38
- i18next.changeLanguage(locale)
39
- }
40
-
41
- // Set the theme class for the document
42
- if (theme === 'dark') {
43
- document.documentElement.classList.add('dark')
44
- document.documentElement.classList.remove('light')
45
- } else {
46
- document.documentElement.classList.add('light')
47
- document.documentElement.classList.remove('dark')
48
- }
49
-
50
- return Story()
51
- }
52
- ]
@@ -1,8 +0,0 @@
1
- import { storybookPlugin } from '@web/dev-server-storybook';
2
- import baseConfig from '../web-dev-server.config.mjs';
3
-
4
- export default /** @type {import('@web/dev-server').DevServerConfig} */ ({
5
- ...baseConfig,
6
- open: '/',
7
- plugins: [storybookPlugin({ type: 'web-components' }), ...baseConfig.plugins],
8
- });
@@ -1,79 +0,0 @@
1
- /**
2
- * Type definition for available filter operators that can be used in query filters.
3
- */
4
- declare type FilterOperator =
5
- | 'search'
6
- | 'eq'
7
- | 'between'
8
- | 'gte'
9
- | 'lte'
10
- | 'is_not_true'
11
- | 'in'
12
- | 'like'
13
- | 'i_like'
14
- | 'noteq'
15
- | 'is_empty_num_id'
16
- | 'is_blank'
17
- | 'is_present'
18
- | 'is_not_false'
19
- | 'is_true'
20
- | 'is_false'
21
- | 'is_not_null'
22
- | 'is_null'
23
- | 'notin_with_null'
24
- | 'notin'
25
- | 'gt'
26
- | 'lt'
27
- | 'i_nlike'
28
- | 'nlike'
29
-
30
- /**
31
- * Type definition for a query filter that can be applied to filter data.
32
- */
33
- declare type QueryFilter = {
34
- name: string
35
- operator: FilterOperator
36
- value: any
37
- }
38
-
39
- /**
40
- * Type definition for sorting parameters that can be applied to sort data in a query.
41
- */
42
- declare type QuerySorter = {
43
- name: string
44
- desc?: boolean
45
- }
46
-
47
- /**
48
- * Type definition for pagination parameters that can be applied to paginate query results.
49
- */
50
- declare type QueryPaginator = {
51
- page?: number
52
- limit?: number
53
- }
54
-
55
- /**
56
- * A utility function to adjust query filters based on changes provided in `filtersChange`.
57
- *
58
- * @param {QueryFilter[]} filters - The current query filters.
59
- * @param {QueryFilter[]} filtersChange - The changes to be applied to the filters.
60
- * @param {boolean} replaceIf - A flag indicating whether to replace existing filters if a filter with the same name exists.
61
- * @returns {QueryFilter[]} The adjusted query filters.
62
- */
63
- export function adjustFilters(
64
- filters: QueryFilter[],
65
- filtersChange: QueryFilter[],
66
- replaceIf: boolean = true
67
- ): QueryFilter[] {
68
- var filtersNew = [...filters]
69
-
70
- filtersChange.forEach(change => {
71
- const idx = (filtersNew || []).findIndex(f => f.name === change.name)
72
- if (idx !== -1 && !replaceIf) {
73
- return
74
- }
75
- idx !== -1 ? filtersNew.splice(idx, 1, change) : filtersNew.push(change)
76
- })
77
-
78
- return filtersNew
79
- }
package/src/async-lock.ts DELETED
@@ -1,27 +0,0 @@
1
- /**
2
- * A simple asynchronous lock utility class that allows controlling access to a critical section.
3
- * It provides a mechanism to create a lock and wait for its release using promises.
4
- */
5
- export class AsyncLock {
6
- unlock?: any
7
- promise? = new Promise(resolve => (this.unlock = resolve))
8
-
9
- /**
10
- * Creates an instance of the AsyncLock class.
11
- *
12
- * @param {boolean} [lock=false] - Optional parameter to lock the instance immediately upon creation.
13
- */
14
- constructor(lock: boolean = false) {
15
- if (lock) {
16
- this.lock()
17
- }
18
- }
19
-
20
- /**
21
- * Locks the instance, making it awaitable until unlocked.
22
- * A new promise is created for the lock, and the existing unlock function is replaced with a new one.
23
- */
24
- lock() {
25
- this.promise = new Promise(resolve => (this.unlock = resolve))
26
- }
27
- }
package/src/clipboard.ts DELETED
@@ -1,41 +0,0 @@
1
- /**
2
- * Copies the specified text to the clipboard.
3
- *
4
- * @param {string} textToCopy - The text to be copied to the clipboard.
5
- * @param {string} [type] - Optional MIME type for the clipboard data (e.g., 'text/plain', 'text/html').
6
- * @returns {Promise<void>} - A promise that resolves when the text is successfully copied to the clipboard.
7
- */
8
- export async function copyToClipboard(textToCopy: string, type?: string): Promise<void> {
9
- if (navigator.clipboard && window.isSecureContext) {
10
- if (type && type !== 'text/plain') {
11
- /* According to experience, chrome seems to support text/html. */
12
- return navigator.clipboard.write([
13
- new ClipboardItem({
14
- [type]: new Blob([textToCopy], { type }),
15
- 'text/plain': new Blob([textToCopy], { type: 'text/plain' })
16
- })
17
- ])
18
- } else {
19
- return navigator.clipboard.write([
20
- new ClipboardItem({
21
- 'text/plain': new Blob([textToCopy], { type: 'text/plain' })
22
- })
23
- ])
24
- }
25
- } else {
26
- let textArea = document.createElement('textarea')
27
-
28
- textArea.value = textToCopy
29
- textArea.style.position = 'fixed'
30
- textArea.style.left = '-999999px'
31
- textArea.style.top = '-999999px'
32
- document.body.appendChild(textArea)
33
- textArea.focus()
34
- textArea.select()
35
-
36
- return new Promise((res, rej) => {
37
- document.execCommand('copy') ? res() : rej()
38
- textArea.remove()
39
- })
40
- }
41
- }
@@ -1,24 +0,0 @@
1
- /*
2
- * inspired by https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
3
- */
4
-
5
- /**
6
- * Finds the closest ancestor element of the given base element that matches the provided CSS selector.
7
- *
8
- * @param {string} selector - The CSS selector to search for.
9
- * @param {Element} base - The base element to start the search from.
10
- * @returns {Element | null} - The closest ancestor element matching the selector, or null if none is found.
11
- */
12
- export function closestElement(selector: string, base: Element) {
13
- function __closestFrom(el: Element | Window | Document | null): Element | null {
14
- if (!el || el === document || el === window) {
15
- return null
16
- }
17
- if ((el as Slottable).assignedSlot) {
18
- el = (el as Slottable).assignedSlot
19
- }
20
- let found = (el as Element).closest(selector)
21
- return found ? found : __closestFrom(((el as Element).getRootNode() as ShadowRoot).host)
22
- }
23
- return __closestFrom(base)
24
- }
@@ -1,42 +0,0 @@
1
- /**
2
- * A regular expression pattern used to parse the pathname into different parts.
3
- * It captures the contextPath, prefix, domain, and path.
4
- * Example: /contextPathPrefix/domain/path/to/resource
5
- */
6
- var CONTEXT_PATH_PREFIX = 'domain|business'
7
-
8
- /**
9
- * Parses the given pathname and extracts information about the contextPath, prefix, domain, and path.
10
- *
11
- * @param {string} pathname - The pathname to parse.
12
- * @returns {object} - An object containing the parsed information:
13
- * - contextPath: The context path portion of the pathname.
14
- * - prefix: The prefix portion of the pathname.
15
- * - domain: The domain portion of the pathname.
16
- * - path: The remaining path after contextPath, prefix, and domain.
17
- */
18
- export function getPathInfo(pathname: string) {
19
- var regexp = new RegExp(`(/(${CONTEXT_PATH_PREFIX})/([^/]+))?(/?.*)`)
20
- var matched = pathname.match(regexp)
21
- var contextPath = matched?.[1] || ''
22
- var prefix = matched?.[2] || ''
23
- var domain = matched?.[3] || ''
24
- var path = matched?.[4]
25
-
26
- return {
27
- contextPath,
28
- prefix,
29
- domain,
30
- path
31
- }
32
- }
33
-
34
- /**
35
- * Sets the context path prefix used for parsing pathnames.
36
- *
37
- * @param {string} contextPathPrefix - The new context path prefix to set.
38
- */
39
- export function setContextPathPrefix(contextPathPrefix?: string) {
40
- console.log('context-path-prefix was just set to ', `'${contextPathPrefix || 'domain|business'}'`)
41
- CONTEXT_PATH_PREFIX = contextPathPrefix || 'domain|business'
42
- }
package/src/cookie.ts DELETED
@@ -1,44 +0,0 @@
1
- /**
2
- * Sets a cookie with the given name, value, and expiration days.
3
- *
4
- * @param {string} cname - The name of the cookie.
5
- * @param {string} cvalue - The value to be stored in the cookie.
6
- * @param {number} exdays - The number of days until the cookie expires.
7
- */
8
- export function setCookie(cname: string, cvalue: string, exdays: number) {
9
- var d = new Date()
10
- d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000)
11
- var expires = 'expires=' + d.toUTCString()
12
- document.cookie = cname + '=' + cvalue + ';' + expires + ';path=/'
13
- }
14
-
15
- /**
16
- * Retrieves the value of a cookie with the given name.
17
- *
18
- * @param {string} cname - The name of the cookie to retrieve.
19
- * @returns {string} - The value of the cookie, or an empty string if the cookie is not found.
20
- */
21
- export function getCookie(cname: string) {
22
- var name = cname + '='
23
- var decodedCookie = decodeURIComponent(document.cookie)
24
- var ca = decodedCookie.split(';')
25
- for (var i = 0; i < ca.length; i++) {
26
- var c = ca[i]
27
- while (c.charAt(0) == ' ') {
28
- c = c.substring(1)
29
- }
30
- if (c.indexOf(name) == 0) {
31
- return c.substring(name.length, c.length)
32
- }
33
- }
34
- return ''
35
- }
36
-
37
- /**
38
- * Deletes a cookie with the given name.
39
- *
40
- * @param {string} name - The name of the cookie to delete.
41
- */
42
- export function deleteCookie(name: string) {
43
- document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;'
44
- }
@@ -1,5 +0,0 @@
1
- export function decodeHTML(html: string) {
2
- var txt = document.createElement('textarea');
3
- txt.innerHTML = html;
4
- return txt.value;
5
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * Detects if the content of an HTMLElement overflows its boundaries.
3
- *
4
- * @param {HTMLElement} el - The HTMLElement to check for overflow.
5
- * @returns {boolean} - `true` if overflow is detected, `false` otherwise.
6
- * @deprecated This function is no longer recommended for use and has been replaced by 'hasOverflow'.
7
- */
8
- export function detectOverflow(el: HTMLElement) {
9
- var styleOverflow = el.style.overflow
10
-
11
- if (!styleOverflow || styleOverflow === 'visible') el.style.overflow = 'hidden'
12
-
13
- var overflowed = el.clientWidth < el.scrollWidth || el.clientHeight < el.scrollHeight
14
-
15
- el.style.overflow = styleOverflow
16
-
17
- return overflowed
18
- }
@@ -1,24 +0,0 @@
1
- /**
2
- * encode form parameter string from object
3
- * @param {Object} obj target object
4
- */
5
- export function encodeFormParams(obj: { [key: string]: any }) {
6
- return Object.keys(obj)
7
- .map(k => `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`)
8
- .join('&')
9
- }
10
-
11
- /**
12
- * encode url parameter string from object
13
- * replace null value to ''
14
- * @param {Object} obj target object
15
- */
16
- export function encodeUrlParams(urlParams: { [key: string]: any }) {
17
- return Object.keys(urlParams)
18
- .filter((key: string) => {
19
- // ignore empty
20
- return !!urlParams[key]
21
- })
22
- .map(key => `${key}=${encodeURIComponent(urlParams[key] || '')}`)
23
- .join('&')
24
- }
@@ -1,62 +0,0 @@
1
- /**
2
- * judge callback function for FileDropHelper.set
3
- */
4
- type JudgeCallback = () => boolean
5
-
6
- /**
7
- * file drop assist class
8
- */
9
- export class FileDropHelper {
10
- /**
11
- * 파일 드롭 영역에서의 file drag&drop과 관련된 이벤트에 대한 처리를 설정한다.
12
- * @param dropArea file drag&drop target area
13
- * @param [judge] file drag&drop과 관련된 이벤트에 대한 judge callback function
14
- */
15
- static set(dropArea: HTMLElement, judge?: JudgeCallback) {
16
- var preventDefaults = (e: Event) => {
17
- if (!judge || judge()) {
18
- e.preventDefault()
19
- e.stopPropagation()
20
- }
21
- }
22
-
23
- var highlight = (e: Event) => {
24
- if (!judge || judge()) {
25
- dropArea.classList.add('candrop')
26
- }
27
- }
28
-
29
- var unhighlight = (e: Event) => {
30
- if (!judge || judge()) {
31
- dropArea.classList.remove('candrop')
32
- }
33
- }
34
-
35
- ;['dragenter', 'dragover', 'dragleave', 'drop'].forEach(event => {
36
- dropArea.addEventListener(event, preventDefaults, false)
37
- })
38
- ;['dragenter', 'dragover'].forEach(event => {
39
- dropArea.addEventListener(event, highlight, false)
40
- })
41
- ;['dragleave', 'drop'].forEach(event => {
42
- dropArea.addEventListener(event, unhighlight, false)
43
- })
44
-
45
- dropArea.addEventListener(
46
- 'drop',
47
- e => {
48
- if (!judge || judge()) {
49
- let dt = e.dataTransfer!
50
- let files = dt.files
51
-
52
- dropArea.dispatchEvent(
53
- new CustomEvent('file-drop', {
54
- detail: [...Array.from(files)]
55
- })
56
- )
57
- }
58
- },
59
- false
60
- )
61
- }
62
- }
package/src/format.ts DELETED
@@ -1,123 +0,0 @@
1
- /*
2
- * Source Code from https://github.com/Mottie/javascript-number-formatter
3
- * 소스코드 출처 : https://github.com/Mottie/javascript-number-formatter
4
- */
5
-
6
- /**
7
- * Formats a number according to the given mask.
8
- *
9
- * ```example
10
- * var formattedValue = format('+$#,##0.00', 12345.67);
11
- * console.log(formattedValue); // Output: +$12,345.67
12
- * ```
13
- *
14
- * @param {any} mask - The formatting mask to apply.
15
- * @param {any} value - The value to format.
16
- * @returns {string} - The formatted string.
17
- */
18
- export function format(mask: string, value: number): string {
19
- if (!mask || isNaN(+value)) {
20
- return value.toString() // return as it is.
21
- }
22
-
23
- let isNegative: boolean,
24
- result: string | RegExpMatchArray | null,
25
- decimal: string,
26
- group: string,
27
- posLeadZero: number,
28
- posTrailZero: number,
29
- posSeparator: number,
30
- part: string[],
31
- szSep: string[],
32
- integer: string,
33
- // find prefix/suffix
34
- len = mask.length,
35
- start = mask.search(/[0-9\-\+#]/),
36
- prefix = start > 0 ? mask.substring(0, start) : '',
37
- // reverse string: not an ideal method if there are surrogate pairs
38
- str = mask.split('').reverse().join(''),
39
- end = str.search(/[0-9\-\+#]/),
40
- offset = len - end,
41
- substr = mask.substring(offset, offset + 1),
42
- indx = offset + (substr === '.' || substr === ',' ? 1 : 0),
43
- suffix = end > 0 ? mask.substring(indx, len) : '',
44
- splittedMask: string[],
45
- splittedValue: string[],
46
- stringValue: string
47
-
48
- // mask with prefix & suffix removed
49
- mask = mask.substring(start, indx)
50
-
51
- // convert any string to number according to formation sign.
52
- value = mask.charAt(0) === '-' ? -value : +value
53
- isNegative = value < 0 ? ((value = -value), true) : false // process only abs(), and turn on flag.
54
-
55
- // search for separator for grp & decimal, anything not digit, not +/- sign, not #.
56
- result = mask.match(/[^\d\-\+#]/g)
57
- decimal = '.' // ( result && result[ result.length - 1 ] ) || '.'; // ','는 소수점이 되지 않게 함
58
- group = (result && result[1] && result[0]) || ',' // treat the left most symbol as group separator
59
-
60
- // split the decimal for the format string if any.
61
- splittedMask = mask.split(decimal)
62
- // Fix the decimal first, toFixed will auto fill trailing zero.
63
- value = parseFloat(value.toFixed((splittedMask[1] && splittedMask[1].length) || 0))
64
- stringValue = +value + '' // convert number to string to trim off *all* trailing decimal zero(es)
65
-
66
- // fill back any trailing zero according to format
67
- posTrailZero = (splittedMask[1] && splittedMask[1].lastIndexOf('0')) || 0 // look for last zero in format
68
- part = stringValue.split('.')
69
- // integer will get !part[1]
70
- if (!part[1] || (part[1] && part[1].length <= posTrailZero)) {
71
- stringValue = (+value).toFixed(posTrailZero + 1)
72
- }
73
- szSep = splittedMask[0].split(group) // look for separator
74
- splittedMask[0] = szSep.join('') // join back without separator for counting the pos of any leading 0.
75
-
76
- posLeadZero = (splittedMask[0] && splittedMask[0].indexOf('0')) || 0
77
- if (posLeadZero > -1) {
78
- while (part[0].length < splittedMask[0].length - posLeadZero) {
79
- part[0] = '0' + part[0]
80
- }
81
- } else if (+part[0] === 0) {
82
- part[0] = ''
83
- }
84
-
85
- splittedValue = stringValue.split('.')
86
- splittedValue[0] = part[0]
87
-
88
- // process the first group separator from decimal (.) only, the rest ignore.
89
- // get the length of the last slice of split result.
90
- posSeparator = (szSep[1] && szSep[szSep.length - 1].length) || 0
91
- if (posSeparator) {
92
- integer = splittedValue[0]
93
- str = ''
94
- offset = integer.length % posSeparator
95
- len = integer.length
96
- for (indx = 0; indx < len; indx++) {
97
- str += integer.charAt(indx) // ie6 only support charAt for sz.
98
- // -posSeparator so that won't trail separator on full length
99
- /* jshint -W018 */
100
- if (!((indx - offset + 1) % posSeparator) && indx < len - posSeparator) {
101
- str += group
102
- }
103
- }
104
- splittedValue[0] = str
105
- }
106
- splittedValue[1] = splittedMask[1] && splittedValue[1] ? decimal + splittedValue[1] : ''
107
-
108
- // remove negative sign if result is zero
109
- result = splittedValue.join('')
110
- if (result === '0' || result === '') {
111
- // remove negative sign if result is zero
112
- isNegative = false
113
- }
114
-
115
- // 앞에 +가 붙는다면 양수일 경우에도 +를 표기해줌
116
- let fixedPlusSign: string
117
-
118
- if (splittedMask[0].substring(0, 1) === '+') fixedPlusSign = isNegative ? '-' : '+'
119
- else fixedPlusSign = isNegative ? '-' : ''
120
-
121
- // put back any negation, combine integer and fraction, and add back prefix & suffix
122
- return prefix + (fixedPlusSign + result) + suffix
123
- }