frontbacked-svg 5.0.0
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/LICENSE +191 -0
- package/README.md +41 -0
- package/dist/main.cjs +3785 -0
- package/dist/main.d.cts +316 -0
- package/dist/main.d.ts +316 -0
- package/dist/main.mjs +3681 -0
- package/package.json +103 -0
- package/src/base64Image.ts +101 -0
- package/src/cssParser.ts +59 -0
- package/src/filters.ts +226 -0
- package/src/font-utils.ts +204 -0
- package/src/get-default-fields-value.ts +64 -0
- package/src/getSvg.ts +284 -0
- package/src/imageHelper.ts +293 -0
- package/src/imagePassportUtils.ts +718 -0
- package/src/images-processor.ts +186 -0
- package/src/main.ts +1354 -0
- package/src/polyfills/DOMParser.ts +28 -0
- package/src/polyfills/File.ts +20 -0
- package/src/polyfills/Image.ts +90 -0
- package/src/svgScaler.ts +179 -0
- package/src/textGenCodeParser.ts +319 -0
- package/src/time.ts +147 -0
- package/src/toolsFunc.ts +79 -0
- package/src/types.ts +177 -0
- package/src/utils.ts +758 -0
- package/src/watermaker.ts +190 -0
package/src/time.ts
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Timestamp } from "firebase/firestore";
|
|
2
|
+
|
|
3
|
+
interface Format {[x: string]: string}
|
|
4
|
+
|
|
5
|
+
export const timestampToDate = (timestamp: Timestamp | Date | null | undefined): Date => {
|
|
6
|
+
try {
|
|
7
|
+
return (timestamp as Timestamp).toDate()
|
|
8
|
+
|
|
9
|
+
} catch(e) {
|
|
10
|
+
return timestamp as Date
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export const dateToTimestamp = (date: Date | Timestamp | null | undefined): Timestamp => {
|
|
14
|
+
try {
|
|
15
|
+
return Timestamp.fromDate(date as Date);
|
|
16
|
+
|
|
17
|
+
} catch (e) {
|
|
18
|
+
return date as Timestamp;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
export function joinTimeSegments(date: Date, formats: (Format | number | string)[], separator: string) {
|
|
22
|
+
function format(m: Format | number | string) {
|
|
23
|
+
//console.log("joinTimeSegments:2", typeof m, m)
|
|
24
|
+
if(typeof m === "string" || typeof m === "number") return m
|
|
25
|
+
let f = new Intl.DateTimeFormat('en', m);
|
|
26
|
+
return f.format(date);
|
|
27
|
+
}
|
|
28
|
+
return formats.map(format).join(separator);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
*
|
|
33
|
+
* @param {The number of seconds to parse into time segments} seconds
|
|
34
|
+
* @param {The number of seconds to parse into time segments} seconds
|
|
35
|
+
* @returns A string that represents the time segments in days, months, weeks, days, hours, minutes, and seconds
|
|
36
|
+
*/
|
|
37
|
+
export const secondsToTimeSegments = (
|
|
38
|
+
seconds: number,
|
|
39
|
+
onSegmentsFrame?: (timeFrame: string, timeFrameUnit: "Y" | "M" | "D" | "H" | "Min" | "S", timeFrameIndex: number) => string
|
|
40
|
+
) => {
|
|
41
|
+
const d = new Date(seconds * 1000).toISOString()
|
|
42
|
+
let segments
|
|
43
|
+
//If seconds is less than an hour returns the format MM:SS
|
|
44
|
+
if(seconds < 3600) {
|
|
45
|
+
segments = d.substring(14, 19)
|
|
46
|
+
|
|
47
|
+
} //If seconds is less than a day(but greater or equal to an hour) returns the format HH:MM:SS
|
|
48
|
+
else if(seconds < 86400) {
|
|
49
|
+
segments = d.substring(11, 19)
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
//If seconds is less than a month(using 31 days in January)(but greater or equal to a day)
|
|
53
|
+
// returns the format DD:HH:MM:SS
|
|
54
|
+
else if(seconds < 2678400) {
|
|
55
|
+
segments = d.replace('T', ':').substring(8, 19)
|
|
56
|
+
var days = `${parseInt(segments.substring(0, 2)) - 1}`
|
|
57
|
+
if(days.length == 1) days = `0${days}`
|
|
58
|
+
segments = `${days}:${segments.substring(3)}`
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
//If seconds is less than a year(but greater or equal to a month)
|
|
63
|
+
// returns the format MM:DD:HH:mm:SS
|
|
64
|
+
else if(seconds < 31536000) {
|
|
65
|
+
segments = d.replace('-', ':').replace('T', ':').substring(5, 19)
|
|
66
|
+
//get the months
|
|
67
|
+
var months = `${parseInt(segments.substring(0, 2)) - 1}`
|
|
68
|
+
if(months.length == 1) months = `0${months}`
|
|
69
|
+
|
|
70
|
+
//get the days
|
|
71
|
+
var days = `${parseInt(segments.substring(3, 5)) - 1}`
|
|
72
|
+
if(days.length == 1) days = `0${days}`
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
segments = `${months}:${days}:${segments.substring(6)}`
|
|
76
|
+
|
|
77
|
+
} //If seconds is greater or equal to a year
|
|
78
|
+
// returns the format YY:MM:DD:HH:mm:SS
|
|
79
|
+
else {
|
|
80
|
+
segments = d.replace('-', ':').replace('T', ':').substring(0, 19)
|
|
81
|
+
//get the year
|
|
82
|
+
var years = `${parseInt(segments.substring(0, 4)) - 1970}`
|
|
83
|
+
if(years.length == 1) years = `0${years}`
|
|
84
|
+
|
|
85
|
+
//get the months
|
|
86
|
+
var months = `${parseInt(segments.substring(5, 7)) - 1}`
|
|
87
|
+
if(months.length == 1) months = `0${months}`
|
|
88
|
+
|
|
89
|
+
//get the days
|
|
90
|
+
var days = `${parseInt(segments.substring(8, 10)) - 1}`
|
|
91
|
+
if(days.length == 1) days = `0${days}`
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
segments = `${years}:${months}:${days}:${segments.substring(11)}`
|
|
95
|
+
}
|
|
96
|
+
if(onSegmentsFrame) {
|
|
97
|
+
const timeFrameUnits: ("Y" | "M" | "D" | "H" | "Min" | "S")[] = ["Y", "M", "D", "H", "Min", "S"]
|
|
98
|
+
const frames = segments.split(":")
|
|
99
|
+
var unitIndex = timeFrameUnits.length - frames.length
|
|
100
|
+
var segs = ""
|
|
101
|
+
for (const frame of frames) {
|
|
102
|
+
segs += onSegmentsFrame(frame, timeFrameUnits[unitIndex], unitIndex)
|
|
103
|
+
unitIndex++
|
|
104
|
+
}
|
|
105
|
+
segments = segs
|
|
106
|
+
}
|
|
107
|
+
return segments
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export const parsePaymentWindow = (seconds: number): {time: string, time_unit: string} => {
|
|
111
|
+
let tm: string | null = null
|
|
112
|
+
let timeUnit: string = ""
|
|
113
|
+
const timeParser = (time: string, unit: string) => {
|
|
114
|
+
if(parseInt(time) > 0 && !tm) {
|
|
115
|
+
tm = `${parseInt(time)}`
|
|
116
|
+
timeUnit = unit
|
|
117
|
+
}
|
|
118
|
+
return `${parseInt(time)} ${unit} `
|
|
119
|
+
}
|
|
120
|
+
secondsToTimeSegments(seconds, timeParser)
|
|
121
|
+
return {
|
|
122
|
+
time: `${tm || ""}`,
|
|
123
|
+
time_unit: timeUnit
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const timestampToGmt = (localTimestamp: number): number => {
|
|
128
|
+
// Create a Date object with the local timestamp
|
|
129
|
+
const localDate = new Date(localTimestamp);
|
|
130
|
+
|
|
131
|
+
// Get the UTC (GMT) equivalent of the timestamp
|
|
132
|
+
const gmtTimestamp = localDate.getTime() + ((new Date()).getTimezoneOffset() * 60000); // 60000 = 60 * 1000 to convert minutes to milliseconds
|
|
133
|
+
|
|
134
|
+
return gmtTimestamp;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export const gmtTimestampToLocal = (gmtTimestamp: number): number => {
|
|
138
|
+
// Create a Date object with the GMT timestamp
|
|
139
|
+
const gmtDate = new Date(gmtTimestamp);
|
|
140
|
+
|
|
141
|
+
// Get the local equivalent of the GMT timestamp by adding the timezone offset
|
|
142
|
+
const localTimestamp = gmtDate.getTime() - ((new Date()).getTimezoneOffset() * 60000);
|
|
143
|
+
|
|
144
|
+
return localTimestamp;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
|
package/src/toolsFunc.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Doc } from "./types.ts"
|
|
2
|
+
|
|
3
|
+
export const getResponsiveX = (value: number, ticketWidth: number, baseTemplateWidth: number, fractionDigits?: number) => {
|
|
4
|
+
if(value == 0) return 0
|
|
5
|
+
value = (value * ticketWidth) / baseTemplateWidth
|
|
6
|
+
if(fractionDigits) {
|
|
7
|
+
//console.log("scaleSvg.getResponsiveX: ", value, ticketWidth, baseTemplateWidth, value.toFixed(fractionDigits))
|
|
8
|
+
return parseFloat(value.toFixed(fractionDigits))
|
|
9
|
+
}
|
|
10
|
+
return Math.ceil(value)
|
|
11
|
+
}
|
|
12
|
+
/*
|
|
13
|
+
scaleSvg.getResponsiveX: 248.0178020590345 512 2047.853 248.018
|
|
14
|
+
toolsFunc.ts:17 scaleSvg.getResponsiveY: 198.01421293422914 341.3332499940181 1365.235 198.014
|
|
15
|
+
toolsFunc.ts:7 scaleSvg.getResponsiveX: 867.3122533697486 512 2047.853 867.312
|
|
16
|
+
toolsFunc.ts:17 scaleSvg.getResponsiveY: 511.0366808555106 341.3332499940181 1365.235 511.037
|
|
17
|
+
toolsFunc.ts:7 scaleSvg.getResponsiveX: 128.50922405074974 512 2047.853 128.509
|
|
18
|
+
toolsFunc.ts:17 scaleSvg.getResponsiveY: 158.76139547125698 341.3332499940181 1365.235 158.761
|
|
19
|
+
toolsFunc.ts:7 scaleSvg.getResponsiveX: 96.75694495649834 512 2047.853 96.757
|
|
20
|
+
toolsFunc.ts:17 scaleSvg.getResponsiveY: 426.28059728896557 341.3332499940181 1365.235 426.281*/
|
|
21
|
+
|
|
22
|
+
export const getResponsiveY = (value: number, ticketHeight: number, baseTemplateHeight: number, fractionDigits?: number) => {
|
|
23
|
+
if(value == 0) return 0
|
|
24
|
+
value = (value * ticketHeight) / baseTemplateHeight
|
|
25
|
+
if(fractionDigits) {
|
|
26
|
+
//console.log("scaleSvg.getResponsiveY: ", value, ticketHeight, baseTemplateHeight, value.toFixed(fractionDigits))
|
|
27
|
+
return parseFloat(value.toFixed(fractionDigits))
|
|
28
|
+
}
|
|
29
|
+
return Math.ceil(value)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const translate = (x: number, y: number, ticketWidth: number, baseTemplateWidth: number, ticketHeight: number, baseTemplateHeight: number) => {
|
|
33
|
+
return `translate(${getResponsiveX(x, ticketWidth, baseTemplateWidth, 3)} ${getResponsiveY(y, ticketHeight, baseTemplateHeight, 3)}) `
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const scale = (x: number, y: number, ticketWidth: number, baseTemplateWidth: number, ticketHeight: number, baseTemplateHeight: number) => {
|
|
37
|
+
return `scale(${getResponsiveX(x, ticketWidth, baseTemplateWidth, 3)} ${getResponsiveY(y, ticketHeight, baseTemplateHeight, 3)}) `
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const pxToVw = (value: number, parentWidth: number, fractionDigits?: number) => {
|
|
41
|
+
if (value === 0) return 0;
|
|
42
|
+
const vwValue = (value * 100) / parentWidth;
|
|
43
|
+
if (fractionDigits) {
|
|
44
|
+
return parseFloat(vwValue.toFixed(fractionDigits));
|
|
45
|
+
}
|
|
46
|
+
return Math.ceil(vwValue);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
function convertToArrayOfObjects(inputObject: Doc) {
|
|
50
|
+
const resultArray: Doc[] = [];
|
|
51
|
+
|
|
52
|
+
// Get the keys and sort them numerically
|
|
53
|
+
const sortedKeys = Object.keys(inputObject).sort((a, b) => parseInt(`${a}`) - parseInt(`${b}`));
|
|
54
|
+
|
|
55
|
+
// Iterate over the sorted keys and push the corresponding values to the array
|
|
56
|
+
sortedKeys.forEach(key => {
|
|
57
|
+
resultArray.push(inputObject[key]);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return resultArray;
|
|
61
|
+
}
|
|
62
|
+
export const arrayAsObjectToArray = (arrayAsObject?: {[x: number]: Doc} | Doc[] | null) => {
|
|
63
|
+
if(!arrayAsObject) return []
|
|
64
|
+
if(Array.isArray(arrayAsObject)) {
|
|
65
|
+
return arrayAsObject
|
|
66
|
+
|
|
67
|
+
} else if(typeof arrayAsObject == "object") {
|
|
68
|
+
return convertToArrayOfObjects(arrayAsObject)
|
|
69
|
+
|
|
70
|
+
} else {
|
|
71
|
+
return []
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const parseContactLink = (contactLink: string, message?: string) => {
|
|
76
|
+
if(!message) return contactLink
|
|
77
|
+
var msg = `${message.replace(/\n/g, "%0A")}`.replace(/[ ]/g, "%20")
|
|
78
|
+
return contactLink.split("?")[0] + `?text=${msg}`
|
|
79
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
export interface Doc {[x: string]: any}
|
|
2
|
+
export interface FileMap {[x: string]: string}
|
|
3
|
+
export interface FileImage {
|
|
4
|
+
id: string;
|
|
5
|
+
image: File;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface FilterArgs {
|
|
9
|
+
[x: string]: any
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface Filters {
|
|
13
|
+
[x: string]: {
|
|
14
|
+
id: string,
|
|
15
|
+
filter: (base64ImageString: string, args?: FilterArgs | null) => Promise<string>;
|
|
16
|
+
isAutomatic?: boolean,
|
|
17
|
+
render?: any//React.FC<{ filterArgs?: FilterArgs | null; setFilterArgs: (newFilterArgs: FilterArgs) => void, filterImage?: string | null, onShowSvgArgsInput?: () => void }> | null;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface Declaration {
|
|
22
|
+
property: string,
|
|
23
|
+
value: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface CssDeclarations {
|
|
27
|
+
declarations: Declaration[],
|
|
28
|
+
shouldReplace?: boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface CssAction {
|
|
32
|
+
[identifier: string]: CssDeclarations
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface CssActions {
|
|
36
|
+
if_selector?: CssAction | null,
|
|
37
|
+
if_property?: CssAction | null,
|
|
38
|
+
if_property_and_value?: CssAction | null
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface Mask { filter_id: string, args?: FilterArgs | null }
|
|
42
|
+
export interface Filter { [filterId: string]: Mask | null }
|
|
43
|
+
|
|
44
|
+
export interface TextSelectSettings {
|
|
45
|
+
[x: string]: {name: string, value: string}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
//Example
|
|
49
|
+
/**
|
|
50
|
+
* {
|
|
51
|
+
Profile_Picture.upload: {
|
|
52
|
+
Blur: {...}
|
|
53
|
+
ImageTranform: {...}
|
|
54
|
+
},
|
|
55
|
+
Signature.sign: {
|
|
56
|
+
Blur: {...}
|
|
57
|
+
ImageTranform: {...}
|
|
58
|
+
}
|
|
59
|
+
* }
|
|
60
|
+
*/
|
|
61
|
+
export interface MaskMap {
|
|
62
|
+
[fieldId: string]: Filter | null
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface MapWithName {
|
|
66
|
+
[x: string]: {
|
|
67
|
+
name: string,
|
|
68
|
+
[x: string]: any
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface FieldsData {
|
|
73
|
+
is_freemium: boolean
|
|
74
|
+
template_id: string
|
|
75
|
+
[x: string]: any
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface Fields extends MapWithName {
|
|
79
|
+
[x: string]: Field
|
|
80
|
+
}
|
|
81
|
+
/*
|
|
82
|
+
export interface Field extends InputBoxProps {
|
|
83
|
+
id: string
|
|
84
|
+
name: string
|
|
85
|
+
info?: string | null
|
|
86
|
+
helperText?: string | null
|
|
87
|
+
placeholder?: string | null
|
|
88
|
+
type: string
|
|
89
|
+
isEditable?: boolean
|
|
90
|
+
index?: number | string | null
|
|
91
|
+
options?: { [x: string]: Field }
|
|
92
|
+
message?: string | null,
|
|
93
|
+
hoverMessage?: string | null,
|
|
94
|
+
ruleMessage?: string | null,
|
|
95
|
+
useImageText?: string | null
|
|
96
|
+
}*/
|
|
97
|
+
export interface Field {
|
|
98
|
+
id: string
|
|
99
|
+
name: string
|
|
100
|
+
type: string
|
|
101
|
+
isEditable?: boolean
|
|
102
|
+
index?: number | string | null
|
|
103
|
+
options?: { [x: string]: Field }
|
|
104
|
+
selections?: {
|
|
105
|
+
[x: string]: {
|
|
106
|
+
name: string,
|
|
107
|
+
value: string
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
useImageText?: string | null
|
|
111
|
+
optional?: boolean | null,
|
|
112
|
+
[x: string]: any
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface Template {
|
|
116
|
+
id: string,
|
|
117
|
+
name: string,
|
|
118
|
+
logo: string,
|
|
119
|
+
is_default: boolean,
|
|
120
|
+
data_url: string,
|
|
121
|
+
split_on_download?: boolean,
|
|
122
|
+
split_on_download_hr?: boolean,
|
|
123
|
+
[x: string]: any
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface TemplateData {
|
|
127
|
+
svg: string,
|
|
128
|
+
fields: Fields,
|
|
129
|
+
images: FileMap,
|
|
130
|
+
masks?: MaskMap | null,
|
|
131
|
+
cssActions?: CssActions | null
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface Templates extends MapWithName {
|
|
135
|
+
[x: string]: Template
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface TemplatesResults {
|
|
139
|
+
templatesLoading: boolean, templatesError?: string | null,
|
|
140
|
+
selectedTemplateLoading: boolean, selectedTemplateError?: string | null,
|
|
141
|
+
parsingTemplate: boolean,
|
|
142
|
+
templates: Templates,
|
|
143
|
+
selectedTemplate?: Template | null,
|
|
144
|
+
selectedTemplateData?: TemplateData | null,
|
|
145
|
+
workingTemplate?: Template | null,
|
|
146
|
+
workingTemplateData?: TemplateData | null,
|
|
147
|
+
setAsDefaulTemplate: ( is_default: boolean ) => void,
|
|
148
|
+
setWorkingTemplate: (template: Template | null | undefined) => void,
|
|
149
|
+
setWorkingTemplateData: (template: TemplateData | null | undefined) => void,
|
|
150
|
+
selectTemplate: (selectedTemplateId: string) => void,
|
|
151
|
+
parseTemplateSvg: (svg: string, isNew: boolean) => Promise<{template: Template, templateData: TemplateData} | null>,
|
|
152
|
+
saveTemplate: (onSetProgressStatus?: (message: string, pct?: number | null) => void) => Promise<string | null>,
|
|
153
|
+
deleteTemplate: (id: string) => void,
|
|
154
|
+
getDefaultTemplateId: (templates: Templates) => string,
|
|
155
|
+
currentTemplateId?: string | null
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface Font {
|
|
159
|
+
name: string,
|
|
160
|
+
id: string,
|
|
161
|
+
file?: File | null,
|
|
162
|
+
ext?: string | null,
|
|
163
|
+
url?: string | null,
|
|
164
|
+
dataUrl?: string | null,
|
|
165
|
+
readError?: string | null,
|
|
166
|
+
writeError?: string | null
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface FontsMap {
|
|
170
|
+
[x: string]: Font
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export interface ImageUploadMaskInfo {
|
|
174
|
+
imageId: string,
|
|
175
|
+
filterId: string,
|
|
176
|
+
mask: Mask
|
|
177
|
+
}
|