@baravak/risloo-profile-cli 4.45.0 → 4.46.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.
@@ -0,0 +1,248 @@
1
+ const gauge = require("../helpers/gauge");
2
+ const { Profile } = require("../Profile");
3
+
4
+ const labels = {
5
+ extremely_high: "فوق بالا",
6
+ very_high: "خیلی بالا",
7
+ high: "بالا",
8
+ average: "متوسط",
9
+ low: "پایین",
10
+ very_low: "خیلی پایین",
11
+ extremely_low: "فوق پایین",
12
+ };
13
+
14
+ const colors = {
15
+ bars: [
16
+ ['#EDE9FE', '#5B21B6', '#7C3AED', '#A78BFA'],
17
+ ]
18
+ }
19
+
20
+ class FRHPT9A extends Profile {
21
+ // Number of pages
22
+ static pages = 1;
23
+
24
+ // Labels of the sample
25
+ labels = {
26
+ L1_1: { eng: "factors_ex_raw", group: true, fa: "برون‌گرایی" },
27
+ L1_2: { eng: "factors_ex_percentage" },
28
+ L1_3: { eng: "factors_ex_level" },
29
+
30
+
31
+ L6_1: { eng: "factors_an_raw", group: true, fa: "رگه اضطراب" },
32
+ L6_2: { eng: "factors_an_percentage" },
33
+ L6_3: { eng: "factors_an_level" },
34
+
35
+
36
+ L11_1: { eng: "factors_dp_raw", group: true, fa: "رگه افسردگی" },
37
+ L11_2: { eng: "factors_dp_percentage" },
38
+ L11_3: { eng: "factors_dp_level" },
39
+
40
+
41
+ L16_1: { eng: "factors_ag_raw", group: true, fa: "خشم و پرخاشگری" },
42
+ L16_2: { eng: "factors_ag_percentage" },
43
+ L16_3: { eng: "factors_ag_level" },
44
+
45
+
46
+ L21_1: { eng: "factors_op_raw", group: true, fa: "گشودگی به تجربه" },
47
+ L21_2: { eng: "factors_op_percentage" },
48
+ L21_3: { eng: "factors_op_level" },
49
+
50
+
51
+ L26_1: { eng: "factors_af_raw", group: true, fa: "عاطفه" },
52
+ L26_2: { eng: "factors_af_percentage" },
53
+ L26_3: { eng: "factors_af_level" },
54
+
55
+
56
+ L31_1: { eng: "factors_co_raw", group: true, fa: "وظیفه‌شناسی" },
57
+ L31_2: { eng: "factors_co_percentage" },
58
+ L31_3: { eng: "factors_co_level" },
59
+
60
+
61
+ L36_1: { eng: "factors_fl_raw", group: true, fa: "انعطاف‌پذیری" },
62
+ L36_2: { eng: "factors_fl_percentage" },
63
+ L36_3: { eng: "factors_fl_level" },
64
+
65
+ L54_1: { eng: "indicators_vrin_value", fa: "دقت در پاسخ‌دهی"},
66
+ L54_2: { eng: "indicators_vrin_level" },
67
+
68
+ L55_1: { eng: "indicators_lie_scale_value", fa: "مطلوب‌نمایی گویه‌ای"},
69
+ L55_2: { eng: "indicators_lie_scale_level" },
70
+
71
+ L56_1: { eng: "indicators_defensiveness_scale_value", fa: "مطلوب‌نمایی مولفه‌ای"},
72
+ L56_2: { eng: "indicators_defensiveness_scale_level" },
73
+
74
+ L57_1: { eng: "indicators_midpoint_responses_value", fa: "احتیاط در پاسخ"},
75
+ L57_2: { eng: "indicators_midpoint_responses_level" },
76
+
77
+ L60_1: { eng: "indicators_validity_median_value", fa: "بیش از ۳۰ پاسخ میانه", length: 116},
78
+ L60_2: { eng: "indicators_validity_median_error" },
79
+ };
80
+
81
+ profileSpec = {
82
+ /* "sample" determines some important info about the sample and profile */
83
+ /* Default prerequisites: 1. gender, 2. age, 3. education */
84
+ /* "prerequisites" is synonym to "fields" in our program */
85
+ sample: {
86
+ name: "پرسشنامه شخصیت ۲۰۲۵ - فرم کوتاه" /* Name of the sample */,
87
+ multiProfile: false /* Whether the sample has multiple profiles or not */,
88
+ questions: false /* Determines whether to get questions from inital dataset or not */,
89
+ defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
90
+ fields: [] /* In case you want to get some additional fields and show in the profile */,
91
+ },
92
+ /* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
93
+ /* calculating its dimensions carefully is of great importance */
94
+ profile: {
95
+ get dimensions() {
96
+ return {
97
+ width: 800 + 2 * this.padding.x,
98
+ height: 529 + 2 * this.padding.y,
99
+ };
100
+ },
101
+ padding: {
102
+ x: 52,
103
+ y: 93,
104
+ },
105
+ },
106
+ labels: Object.values(this.labels),
107
+ };
108
+
109
+ constructor(dataset, options, config = {}) {
110
+ super();
111
+ this._init(dataset, options, config);
112
+ }
113
+
114
+ _calcContext() {
115
+ const {
116
+ dataset,
117
+ } = this;
118
+ const groups = new FG(dataset.score.slice(0, 24)).generate()
119
+ const ind = dataset.score.slice(24, 32)
120
+ const indicators = []
121
+ for(let i = 0; i < ind.length; i += 2){
122
+ const indicator = ind[i]
123
+ const level = ind[i + 1]
124
+ indicators.push({
125
+ ...indicator,
126
+ mark : indicator.mark ?? 0,
127
+ level: level.mark,
128
+ levelText: labels[level.mark]
129
+ })
130
+ }
131
+ indicators.reverse()
132
+ const validityList = dataset.score.slice(32, 34)
133
+ let validities = []
134
+ for(let i = 0; i < validityList.length; i += 2){
135
+ const validity = validityList[i]
136
+ const error = validityList[i + 1]
137
+ if(error.mark === undefined || error.mark === null) continue
138
+ validities.push({
139
+ error: validity.label.fa,
140
+ length: validity.label.length
141
+ })
142
+ }
143
+ let start = 0
144
+ validities = validities.map((v,i) => {
145
+ const result ={
146
+ ...v,
147
+ start,
148
+ last: validities.length - 1 === i
149
+ }
150
+ start += v.length + 54
151
+ return result
152
+ })
153
+ const groupList = Object.values(groups).map(r => ({...r, length: r.subs.length}))
154
+ return [
155
+ { page: 1, titleAppend: '', groups: groupList, colors, indicators: indicators, validityErrors: validities }
156
+ ];
157
+ }
158
+ }
159
+ function rowMap(r, i){
160
+ return {
161
+ ...r,
162
+ color: i % 2 === 0 ? colors.bars[0] : colors.bars[1],
163
+ bg: `url(#${i % 2 === 0 ? 'bgbar1' : 'bgbar2'})`
164
+ }
165
+ }
166
+
167
+ class FG {
168
+ factors = {};
169
+ _result = {};
170
+ _current = "";
171
+ _index = -1;
172
+ constructor(factors) {
173
+ this.factors = factors;
174
+ }
175
+
176
+ generate() {
177
+ let common = {};
178
+ let sKey = "";
179
+ let gKey = ''
180
+ for (const factor of this.factors) {
181
+ const parse = this.parse(factor);
182
+ const [key, sub, group, isGroup] = parse;
183
+ if (key !== sKey) {
184
+ this.current(group);
185
+ if(gKey !== ''){
186
+ if(this._result[gKey] === undefined ){
187
+ this._result[gKey] = common;
188
+ }else{
189
+ this._result[gKey].subs.push(common)
190
+ }
191
+ }
192
+ sKey = key;
193
+ gKey = group
194
+ common = { ...this.raw(factor), key: key.toUpperCase()};
195
+ if(isGroup){
196
+ common.subs = []
197
+ }
198
+ } else {
199
+ if (sub === "percentage") {
200
+ const [p, t] = this.percentage(factor);
201
+ common.percentage = p;
202
+ common.percentageText = t;
203
+ } else {
204
+ const [l, t] = this.label(factor);
205
+ common.level = l;
206
+ common.levelText = t;
207
+ }
208
+ }
209
+ }
210
+ if(this._result[gKey] === undefined){
211
+ this._result[gKey] = common
212
+ }else{
213
+ this._result[gKey].subs.push(common)
214
+ }
215
+ return this._result
216
+ }
217
+
218
+ raw(factor) {
219
+ return {
220
+ ...factor,
221
+ mark: factor.mark ?? 0,
222
+ };
223
+ }
224
+
225
+ percentage(factor) {
226
+ const mark = factor.mark ?? 0;
227
+ return [mark, Math.round(mark * 100)];
228
+ }
229
+
230
+ label(factor) {
231
+ return [factor.mark, labels[factor.mark]];
232
+ }
233
+
234
+ parse(factor) {
235
+ const [key, sub] = factor?.label?.eng?.replace(/^factors_/, "").split("_");
236
+ const isGroup = !/\d$/.test(key);
237
+ const group = key.replace(/\d$/, "");
238
+ return [key, sub, group, isGroup];
239
+ }
240
+ current(group) {
241
+ if (this._current !== group) {
242
+ this._current = group;
243
+ this._index++;
244
+ }
245
+ }
246
+ }
247
+
248
+ module.exports = FRHPT9A;
@@ -10,16 +10,16 @@ class JRAQ93 extends Profile {
10
10
 
11
11
  // Labels of the sample
12
12
  labels = {
13
- L1: { eng: "research_total_raw", fr: "نمره کل پژوهشی", max: 260 },
13
+ L1: { eng: "research_total_raw", fr: "نمره کل پژوهشی", max: 180 },
14
14
  L1_P: { eng: "research_total_percentage"},
15
15
 
16
- L2: { eng: "research_adherence_raw", fr: "پایبندی", max: 88 },
16
+ L2: { eng: "research_adherence_raw", fr: "پایبندی", max: 66 },
17
17
  L2_P: { eng: "research_adherence_percentage"},
18
18
 
19
- L3: { eng: "research_ambivalence_raw", fr: "دوسوگرایی", max: 84 },
19
+ L3: { eng: "research_ambivalence_raw", fr: "دوسوگرایی", max: 63 },
20
20
  L3_P: { eng: "research_ambivalence_percentage"},
21
21
 
22
- L4: { eng: "research_disobedience_raw", fr: "ناپایبندی", max: 68 },
22
+ L4: { eng: "research_disobedience_raw", fr: "ناپایبندی", max: 51 },
23
23
  L4_P: { eng: "research_disobedience_percentage"},
24
24
 
25
25
  L5: { eng: "clinical_total_raw", fr: "نمره کل بالینی", max: 60 },
@@ -28,8 +28,8 @@ class JRAQ93 extends Profile {
28
28
  L6: { eng: "clinical_adherence_raw", fr: "پایبندی", max: 22 },
29
29
  L6_P: { eng: "clinical_adherence_percentage"},
30
30
 
31
- L7: { eng: "clinical_ambivalence__raw", fr: "دوسوگرایی", max: 21 },
32
- L7_P: { eng: "clinical_ambivalence__percentage"},
31
+ L7: { eng: "clinical_ambivalence_raw", fr: "دوسوگرایی", max: 21 },
32
+ L7_P: { eng: "clinical_ambivalence_percentage"},
33
33
 
34
34
  L8: { eng: "clinical_disobedience_raw", fr: "ناپایبندی", max: 17 },
35
35
  L8_P: { eng: "clinical_disobedience_percentage"},
@@ -0,0 +1,117 @@
1
+ {{#> layout}}
2
+
3
+ <defs>
4
+ <linearGradient id="bgbarg">
5
+ <stop stop-color="{{colors.bars.[0].[0]}}"/>
6
+ <stop offset="1" stop-color="{{colors.bars.[0].[1]}}"/>
7
+ </linearGradient>
8
+ <clipPath id="cbgbarg">
9
+ {{bar 480 16 (object tl=0 bl=0 tr=2 br=2) (toRad 0)}}
10
+ </clipPath>
11
+ <linearGradient id="bgind" x1="97" y1="0" x2="97" y2="83" gradientUnits="userSpaceOnUse">
12
+ <stop stop-color="#F8FAFC"/>
13
+ <stop offset="1" stop-color="#F5F3FF"/>
14
+ </linearGradient>
15
+ <linearGradient id="error" x1="15" y1="15" x2="0" y2="15" gradientUnits="userSpaceOnUse">
16
+ <stop stop-color="#FFF1F2"/>
17
+ <stop offset="1" stop-color="#FECDD3"/>
18
+ </linearGradient>
19
+ <filter id="split" x="0" y="0" width="7" height="342" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
20
+ <feFlood flood-opacity="0" result="BackgroundImageFix"/>
21
+ <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
22
+ <feOffset dx="1"/>
23
+ <feGaussianBlur stdDeviation="1.5"/>
24
+ <feComposite in2="hardAlpha" operator="out"/>
25
+ <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
26
+ <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_5334_134825"/>
27
+ <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_5334_134825" result="shape"/>
28
+ </filter>
29
+ </defs>
30
+ <g transform="translate({{spec.profile.padding.x}}, {{spec.profile.padding.y}})">
31
+ <g>
32
+ <g transform="translate(0, 48)">
33
+ <g>
34
+ {{#each groups as |item index|}}
35
+ <g transform="translate(0, {{math index '*' 40}})">
36
+ <rect width="800" height="40" fill="{{ternary (even index) '#F8FAFC' 'none'}}" rx="8" />
37
+ {{bar 480 16 (object tl=0 bl=0 tr=2 br=2) (toRad 0) fill='#E2E8F080' transform='translate(158, 12)'}}
38
+ </g>
39
+ {{/each}}
40
+ </g>
41
+ <g>
42
+ <text x="156.5" y="-24" font-size="12" font-weight="400" dy=".3em" fill="#94A3B8" text-anchor="middle">0</text>
43
+ <text x="397.5" y="-24" font-size="12" font-weight="400" dy=".3em" fill="#94A3B8" text-anchor="middle">50 ٪</text>
44
+ <text x="632" y="-24" font-size="12" font-weight="400" dy=".3em" fill="#94A3B8" text-anchor="middle">100 ٪</text>
45
+ <text x="754" y="-19" font-size="12" font-weight="500" dy=".3em" fill="#64748B" text-anchor="middle">رده‌بندی</text>
46
+ <text x="677" y="-33" font-size="12" font-weight="500" dy=".3em" fill="#64748B" text-anchor="middle">نمره خام</text>
47
+ <text x="677" y="-19" font-size="12" font-weight="500" dy=".3em" fill="#64748B" text-anchor="middle">از 60</text>
48
+ <line x1="277.5" y1="-8.5" x2="277.5" y2="326.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="5.5 5.5"/>
49
+ <line x1="397.5" y1="-8.5" x2="397.5" y2="326.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="5.5 5.5"/>
50
+ <line x1="517.5" y1="-8.5" x2="517.5" y2="326.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="5.5 5.5"/>
51
+ <line x1="637.5" y1="-8.5" x2="637.5" y2="326.5" stroke="#E2E8F0" stroke-linecap="round" stroke-dasharray="5.5 5.5"/>
52
+ <rect x="709" y="-48" width="1" height="376" fill="#F1F5F9"/>
53
+
54
+ </g>
55
+ <g>
56
+ {{#each groups as |item index|}}
57
+ <g transform="translate(0, {{math index '*' 40}})">
58
+ {{# if (boolean key '!==' 'MO')}}
59
+ <g transform='translate(158, 12)'>
60
+ {{bar (math 480 '*' percentage) 16 (object tl=0 bl=0 tr=2 br=2) (toRad 0) fill='url(#bgbarg)' clip-path='url(#cbgbarg)'}}
61
+ <text x="{{math (math 480 '*' percentage) '+' (ternary (boolean percentage '<=' 0.24) 4 -6)}}" y="8" font-size="13" font-weight="500" dy=".3em" fill="{{ternary (boolean percentage '<=' 0.24) ../colors.bars.[0].[1] 'white'}}" text-anchor="{{ternary (boolean percentage '<=' 0.24) 'end' 'start'}}">
62
+ {{percentageText}} ٪
63
+ </text>
64
+ </g>
65
+ <rect x="659" y="11" width="36" height="18" rx="4" fill="{{../colors.bars.[0].[2]}}" />
66
+ <text x="677" y="20" font-size="13" font-weight="500" dy=".3em" fill="white" text-anchor="middle">{{item.mark}}</text>
67
+ <text x="755" y="20" font-size="12" font-weight="400" dy=".3em" fill="#64748B" text-anchor="middle">{{item.levelText}}</text>
68
+ <text x="149" y="20" font-size="13" font-weight="400" dy=".3em" fill="#475569" text-anchor="start">{{item.key}}</text>
69
+ <text x="121" y="20" font-size="13" font-weight="400" dy=".3em" fill="#475569" text-anchor="start">-</text>
70
+ <text x="110" y="20" font-size="13" font-weight="400" dy=".3em" fill="#475569" text-anchor="start">{{item.label.fa}}</text>
71
+ {{else}}
72
+ <rect x="659" y="11" width="36" height="18" rx="4" fill="#CBD5E1" />
73
+ <text x="677" y="20" font-size="13" font-weight="500" dy=".3em" fill="white" text-anchor="middle">-</text>
74
+ <text x="755" y="20" font-size="13" font-weight="500" dy=".3em" fill="#64748B" text-anchor="middle">-</text>
75
+ <text x="149" y="20" font-size="13" font-weight="400" dy=".3em" fill="#94A3B8" text-anchor="start">{{item.key}}</text>
76
+ <text x="121" y="20" font-size="13" font-weight="400" dy=".3em" fill="#94A3B8" text-anchor="start">-</text>
77
+ <text x="110" y="20" font-size="13" font-weight="400" dy=".3em" fill="#94A3B8" text-anchor="start">{{item.label.fa}}</text>
78
+ {{/if}}
79
+
80
+ </g>
81
+ {{/each}}
82
+ </g>
83
+ <g opacity="0.5" filter="url(#split)" transform="translate(154.5, -10.5)">
84
+ <line x1="2.5" y1="3.5" x2="2.5" y2="338.5" stroke="white" stroke-linecap="round"/>
85
+ </g>
86
+ </g>
87
+ </g>
88
+ <g transform="translate(0, 392)">
89
+ {{#each indicators as |item index|}}
90
+ <g transform="translate({{math index '*' 202}}, 0)">
91
+ <rect width="194" height="83" fill="url(#bgind)" stroke="#EDE9FE" rx="8" />
92
+ <text x="142" y="29.5" font-size="16" font-weight="600" dy=".3em" fill="#5B21B6" text-anchor="middle">{{item.mark}}</text>
93
+ <text x="72" y="29.5" font-size="14" font-weight="500" dy=".3em" fill="#334155" text-anchor="middle">{{item.levelText}}</text>
94
+ <path d="M 8.78 3.78 h -8.75 m 0 0 l 3.75 3.75 m -3.75 -3.75 l 3.75 -3.75" stroke="#94A3B8" stroke-linecap="round" stroke-linejoin="round" transform="translate(112.62, 25.75)"/>
95
+ <text x="97" y="55" font-size="13" font-weight="400" dy=".3em" fill="#64748B" text-anchor="middle">{{item.label.fa}}</text>
96
+ </g>
97
+ {{/each}}
98
+ </g>
99
+ {{#if validityErrors}}
100
+ <g transform="translate(0, 483)">
101
+ <rect width="800" height="46" fill="#FFF1F2" stroke="#FECDD3" rx="8" />
102
+ <path d="M 8.9 5.63 v 3.5556 m 0 2.6667 h 0.0089 m -1.464 -11.0303 l -7.2053 12.0303 c -0.1485 0.2572 -0.2271 0.5488 -0.228 0.8459 c -0.0009 0.297 0.0761 0.5891 0.2231 0.8472 c 0.1471 0.258 0.3591 0.4731 0.6151 0.6238 c 0.256 0.1507 0.5469 0.2317 0.844 0.2351 h 14.4125 c 0.2968 -0.0035 0.5877 -0.0845 0.8435 -0.2352 c 0.2559 -0.1506 0.4679 -0.3656 0.6149 -0.6235 c 0.147 -0.258 0.224 -0.5499 0.2233 -0.8468 c -0.0008 -0.2969 -0.0792 -0.5884 -0.2275 -0.8456 l -7.2053 -12.0321 c -0.1516 -0.2502 -0.3652 -0.4571 -0.6201 -0.6007 c -0.2549 -0.1436 -0.5425 -0.219 -0.8351 -0.219 c -0.2926 0 -0.5802 0.0754 -0.8351 0.219 c -0.2549 0.1436 -0.4685 0.3505 -0.6201 0.6007 v 0.0009 z" transform="translate(729.61, 15.04)" fill="none" stroke="#BE123C" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
103
+ <text x="690" y="23" font-size="14" font-weight="500" dy=".3em" fill="#BE123C" text-anchor="middle">فاقد اعتبار</text>
104
+ <path d="M 0 0 l 15 -15 l 0 30 l -15 -15 z" fill="url(#error)" transform="translate(580, 23)"/>
105
+ <g transform="translate(0, 23)">
106
+ {{#each validityErrors as |error index|}}
107
+ <text x="{{math 532 '-' (math start '+' (math length '/' 2))}}" y="0" font-size="13" font-weight="400" dy=".3em" fill="#57534E" text-anchor="middle">{{error.error}}</text>
108
+ {{#if (boolean error.last '===' false)}}
109
+ <circle cx="{{math 532 '-' (math start '+' (math length '+' 26))}}" cy="2" r="2" fill="#A1A1AA"/>
110
+ {{/if}}
111
+ {{/each}}
112
+ </g>
113
+ </g>
114
+ {{/if}}
115
+ </g>
116
+
117
+ {{/layout}}