@baravak/risloo-profile-cli 4.46.3 → 4.75.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/.agents/skills/create-profile/SKILL.md +14 -0
- package/.claude/settings.local.json +1 -3
- package/.claude/skills/create-profile/SKILL.md +203 -0
- package/AGENTS.md +413 -0
- package/CLAUDE.md +2 -185
- package/package.json +1 -1
- package/src/cli-commands/Executor.js +8 -2
- package/src/cli-commands/ExtractExecutor.js +55 -21
- package/src/cli-commands/GiftExecutor.js +1 -0
- package/src/handlebars/importPartials.js +10 -44
- package/src/handlebars/init.js +17 -11
- package/src/publish/json/profiles/BSSI93.json +392 -0
- package/src/publish/json/profiles/FRHPT93.json +2 -2
- package/src/publish/json/profiles/ISKS93.json +288 -0
- package/src/publish/json/profiles/MCMI9A.json +1540 -0
- package/src/publish/json/profiles/NEO93.json +3858 -0
- package/src/publish/json/profiles/NEO9A.json +1159 -1
- package/src/publish/json/profiles/NEO9Q.json +3856 -0
- package/src/publish/json/profiles/NEO9V.json +1157 -0
- package/src/publish/json/profiles/RIASEC9A.json +2775 -0
- package/src/publish/json/profiles/RSI93.json +359 -0
- package/src/samples/AEQ93.js +1 -1
- package/src/samples/AMS93.js +1 -1
- package/src/samples/AMS9A.js +3 -1
- package/src/samples/BAOMEIS93.js +1 -1
- package/src/samples/BEQI93.js +1 -1
- package/src/samples/BSCT93.js +5 -0
- package/src/samples/BSSI93.js +93 -0
- package/src/samples/CAATS93.js +1 -1
- package/src/samples/CERQ93.js +1 -1
- package/src/samples/CRAAS93.js +1 -1
- package/src/samples/DSWLS93.js +1 -1
- package/src/samples/EMSS93.js +1 -1
- package/src/samples/EPQ9A.js +6 -1
- package/src/samples/FACES93.js +6 -0
- package/src/samples/FRHPT93.js +41 -13
- package/src/samples/GMIT93.js +1 -1
- package/src/samples/HPL93.js +1 -1
- package/src/samples/ISKS93.js +62 -0
- package/src/samples/IUS93.js +1 -1
- package/src/samples/JCSI93.js +1 -1
- package/src/samples/JPFQ93.js +5 -0
- package/src/samples/KJGI93.js +1 -1
- package/src/samples/LMIQ93.js +1 -1
- package/src/samples/MCMI9A.js +530 -0
- package/src/samples/MMFAD93.js +1 -1
- package/src/samples/MOCI93.js +1 -1
- package/src/samples/NEO93.js +279 -0
- package/src/samples/NEO9A.js +93 -60
- package/src/samples/NEO9Q.js +281 -0
- package/src/samples/NEO9V.js +218 -0
- package/src/samples/OBQ4493.js +1 -1
- package/src/samples/PIES93.js +1 -1
- package/src/samples/PIES9A.js +4 -0
- package/src/samples/PMCIEF93.js +7 -1
- package/src/samples/PSWQ93.js +1 -1
- package/src/samples/RIASEC93.js +1 -1
- package/src/samples/RIASEC9A.js +256 -0
- package/src/samples/RSI93.js +89 -0
- package/src/samples/SASQ93.js +1 -1
- package/src/samples/SDCAQ93.js +1 -1
- package/src/samples/STAIY93.js +1 -1
- package/src/samples/WAQ93.js +1 -1
- package/src/samples/YBOCS93.js +1 -1
- package/src/samples/YPI93.js +5 -1
- package/views/profiles/MCMI9A_facets_partial.hbs +96 -0
- package/views/profiles/MCMI9A_main_partial.hbs +262 -0
- package/views/profiles/MCMI9A_noteworthy_partial.hbs +66 -0
- package/views/profiles/MCMI9A_vertical_label_partial.hbs +8 -0
- package/views/profiles/NEO_long_facets.hbs +125 -0
- package/views/profiles/NEO_main.hbs +152 -0
- package/views/profiles/NEO_short_facets.hbs +82 -0
- package/views/profiles/samples/BSCT93.hbs +17 -17
- package/views/profiles/samples/BSSI93.hbs +102 -0
- package/views/profiles/samples/FRHPT93_1.hbs +568 -87
- package/views/profiles/samples/FRHPT93_2.hbs +90 -76
- package/views/profiles/samples/FRHPT93_3.hbs +2 -2
- package/views/profiles/samples/FRHPT93_4.hbs +2 -2
- package/views/profiles/samples/FRHPT93_5.hbs +103 -0
- package/views/profiles/samples/FRHPT9A.hbs +7 -7
- package/views/profiles/samples/ISKS93.hbs +38 -0
- package/views/profiles/samples/MCMI9A_1.hbs +3 -0
- package/views/profiles/samples/MCMI9A_2.hbs +3 -0
- package/views/profiles/samples/MCMI9A_3.hbs +3 -0
- package/views/profiles/samples/MCMI9A_4.hbs +3 -0
- package/views/profiles/samples/NEO93_1.hbs +14 -0
- package/views/profiles/samples/NEO93_2.hbs +15 -0
- package/views/profiles/samples/NEO93_3.hbs +15 -0
- package/views/profiles/samples/NEO9A.hbs +14 -29
- package/views/profiles/samples/NEO9Q_1.hbs +13 -0
- package/views/profiles/samples/NEO9Q_2.hbs +14 -0
- package/views/profiles/samples/NEO9Q_3.hbs +14 -0
- package/views/profiles/samples/NEO9V_1.hbs +13 -0
- package/views/profiles/samples/NEO9V_2.hbs +3 -0
- package/views/profiles/samples/RIASEC9A_1.hbs +38 -0
- package/views/profiles/samples/RIASEC9A_2.hbs +67 -0
- package/views/profiles/samples/RIASEC9A_3.hbs +93 -0
- package/views/profiles/samples/RSI93.hbs +101 -0
- package/a.json +0 -4805
- package/src/publish/json/profiles/BSCT93_t1.json +0 -512
- package/src/publish/json/profiles/BSCT93_t2.json +0 -512
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
const { Profile, Mappings } = require("../Profile");
|
|
2
|
+
|
|
3
|
+
class RIASEC9A extends Profile {
|
|
4
|
+
// Number of pages
|
|
5
|
+
static pages = 3;
|
|
6
|
+
|
|
7
|
+
// Labels of the sample
|
|
8
|
+
labels = {
|
|
9
|
+
L1_0: { eng: "realistic_raw", fr: "واقعگرا", short: "و", enShort:"R" },
|
|
10
|
+
L1_1: { eng: "realistic_percentage" },
|
|
11
|
+
L1_2: { eng: "realistic_rank" },
|
|
12
|
+
L1_3: { eng: "realistic_congruence" },
|
|
13
|
+
L1_4: { eng: "realistic_calibrated" },
|
|
14
|
+
L2_0: { eng: "investigative_raw", fr: "جستجوگر", short: "ج", enShort:"I" },
|
|
15
|
+
L2_1: { eng: "investigative_percentage" },
|
|
16
|
+
L2_2: { eng: "investigative_rank" },
|
|
17
|
+
L2_3: { eng: "investigative_congruence" },
|
|
18
|
+
L2_4: { eng: "investigative_calibrated" },
|
|
19
|
+
L3_0: { eng: "artistic_raw", fr: "هنری", short: "هـ", enShort:"A" },
|
|
20
|
+
L3_1: { eng: "artistic_percentage" },
|
|
21
|
+
L3_2: { eng: "artistic_rank" },
|
|
22
|
+
L3_3: { eng: "artistic_congruence" },
|
|
23
|
+
L3_4: { eng: "artistic_calibrated" },
|
|
24
|
+
L4_0: { eng: "social_raw", fr: "اجتماعی", short: "الف", enShort:"S" },
|
|
25
|
+
L4_1: { eng: "social_percentage" },
|
|
26
|
+
L4_2: { eng: "social_rank" },
|
|
27
|
+
L4_3: { eng: "social_congruence" },
|
|
28
|
+
L4_4: { eng: "social_calibrated" },
|
|
29
|
+
L5_0: { eng: "enterprising_raw", fr: "متهور", short: "م", enShort:"E" },
|
|
30
|
+
L5_1: { eng: "enterprising_percentage" },
|
|
31
|
+
L5_2: { eng: "enterprising_rank" },
|
|
32
|
+
L5_3: { eng: "enterprising_congruence" },
|
|
33
|
+
L5_4: { eng: "enterprising_calibrated" },
|
|
34
|
+
L6_0: { eng: "conventional_raw", fr: "قراردادی", short: "ق", enShort:"C" },
|
|
35
|
+
L6_1: { eng: "conventional_percentage" },
|
|
36
|
+
L6_2: { eng: "conventional_rank" },
|
|
37
|
+
L6_3: { eng: "conventional_congruence" },
|
|
38
|
+
L6_4: { eng: "conventional_calibrated" },
|
|
39
|
+
Llt: { eng: "code_letters_abbr" },
|
|
40
|
+
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
profileSpec = {
|
|
44
|
+
/* "sample" determines some important info about the sample and profile */
|
|
45
|
+
/* Default prerequisites: 1. gender, 2. age, 3. education */
|
|
46
|
+
/* "prerequisites" is synonym to "fields" in our program */
|
|
47
|
+
sample: {
|
|
48
|
+
name: "پرسشنامه رغبتسنج تحصیلی - شغلی هالند - ویرایش حوزه" /* Name of the sample */,
|
|
49
|
+
multiProfile: false /* Whether the sample has multiple profiles or not */,
|
|
50
|
+
questions: true /* Determines whether to get questions from inital dataset or not */,
|
|
51
|
+
defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
|
|
52
|
+
fields: [] /* In case you want to get some additional fields and show in the profile */,
|
|
53
|
+
},
|
|
54
|
+
/* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
|
|
55
|
+
/* calculating its dimensions carefully is of great importance */
|
|
56
|
+
profile: {
|
|
57
|
+
get dimensions() {
|
|
58
|
+
return [
|
|
59
|
+
{
|
|
60
|
+
width: 602 + 2 * this.padding[0].x,
|
|
61
|
+
height: 595 + 2 * this.padding[0].y,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
width: 592 + 2 * this.padding[1].x,
|
|
65
|
+
height: 523 + 2 * this.padding[1].y,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
width: 686 + 2 * this.padding[2].x,
|
|
69
|
+
height: 404 + 2 * this.padding[2].y,
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
},
|
|
73
|
+
padding: [
|
|
74
|
+
{
|
|
75
|
+
x: 0,
|
|
76
|
+
y: 51,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
x: 147,
|
|
80
|
+
y: 96,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
x: 109,
|
|
84
|
+
y: 155,
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
/* "items" is the general term used for independent data elements to be drawn in the profile */
|
|
89
|
+
items: {
|
|
90
|
+
offsetY: 32 /* Horizontal offset between two top items */,
|
|
91
|
+
get distanceY() {
|
|
92
|
+
return this.offsetY + this.rect.body.height;
|
|
93
|
+
} /* Horizontal distance between two top items */,
|
|
94
|
+
maxValue: 50 /* Maximum value of items */,
|
|
95
|
+
rect: {
|
|
96
|
+
base: {
|
|
97
|
+
height: 4,
|
|
98
|
+
},
|
|
99
|
+
body: {
|
|
100
|
+
height: 8,
|
|
101
|
+
brs: {
|
|
102
|
+
tl: 0,
|
|
103
|
+
tr: 4,
|
|
104
|
+
bl: 0,
|
|
105
|
+
br: 0,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
widthCoeff: 500 / 56,
|
|
109
|
+
opacityMappings: new Mappings()
|
|
110
|
+
.addMapping("1-10", 0.6)
|
|
111
|
+
.addMapping("11-20", 0.7)
|
|
112
|
+
.addMapping("21-30", 0.8)
|
|
113
|
+
.addMapping("31-40", 0.9)
|
|
114
|
+
.addMapping("41-50", 1) /* Opacity mapping for marks */,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
/* "labels" part which has to be provided for each profile */
|
|
118
|
+
labels: Object.values(this.labels),
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
constructor(dataset, options, config = {}) {
|
|
122
|
+
super();
|
|
123
|
+
this._init(dataset, options, config);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
_calcContext() {
|
|
127
|
+
const {
|
|
128
|
+
spec: { parameters: spec },
|
|
129
|
+
dataset,
|
|
130
|
+
} = this;
|
|
131
|
+
|
|
132
|
+
// Deconstructing the Spec of the Profile
|
|
133
|
+
const { items: itemsSpec } = spec;
|
|
134
|
+
const Items = [];
|
|
135
|
+
for (let i = 0; i < 30; i += 5) {
|
|
136
|
+
const item = dataset.score[i];
|
|
137
|
+
item.percentage = dataset.score[i + 1].mark ?? 0;
|
|
138
|
+
item.rank = dataset.score[i + 2].mark ?? 0;
|
|
139
|
+
item.congruence = dataset.score[i + 3].mark ?? 0;
|
|
140
|
+
item.calibrated = dataset.score[i + 4].mark ?? 0;
|
|
141
|
+
Items.push(item);
|
|
142
|
+
}
|
|
143
|
+
const map = new Map(Items.map(i => [i.label.enShort, i.label.short]))
|
|
144
|
+
const reportMap = dataset.score[30].mark.split('-').map(r => {
|
|
145
|
+
return r.split(',').map(key => map.get(key)).join(' - ')
|
|
146
|
+
}).reverse()
|
|
147
|
+
// Gathering required info for page 1 items
|
|
148
|
+
const items = Items.map((data) => ({
|
|
149
|
+
label: data.label,
|
|
150
|
+
mark: data.mark,
|
|
151
|
+
width: data.mark * itemsSpec.rect.widthCoeff,
|
|
152
|
+
opacity: itemsSpec.rect.opacityMappings.map(data.mark),
|
|
153
|
+
percentage: data.percentage,
|
|
154
|
+
rank: data.rank,
|
|
155
|
+
congruence: data.congruence,
|
|
156
|
+
calibrated: data.calibrated,
|
|
157
|
+
}));
|
|
158
|
+
const questionItems = [
|
|
159
|
+
{
|
|
160
|
+
label: "فعالیتها",
|
|
161
|
+
marks: Array(6)
|
|
162
|
+
.fill(11)
|
|
163
|
+
.map((n, index) =>
|
|
164
|
+
dataset.questions
|
|
165
|
+
.slice(index * n, (index + 1) * n)
|
|
166
|
+
.reduce((sum, { user_answered }) => sum + (+user_answered !== 2 ? 1 : 0), 0)
|
|
167
|
+
),
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
label: "تجربهها",
|
|
171
|
+
marks: Array(6)
|
|
172
|
+
.fill(11)
|
|
173
|
+
.map((n, index) =>
|
|
174
|
+
dataset.questions
|
|
175
|
+
.slice(66 + index * n, 66 + (index + 1) * n)
|
|
176
|
+
.reduce((sum, { user_answered }) => sum + (+user_answered !== 2 ? 1 : 0), 0)
|
|
177
|
+
),
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
label: "مشاغل",
|
|
181
|
+
marks: Array(6)
|
|
182
|
+
.fill(14)
|
|
183
|
+
.map((n, index) =>
|
|
184
|
+
dataset.questions
|
|
185
|
+
.slice(132 + index * n, 132 + (index + 1) * n)
|
|
186
|
+
.reduce((sum, { user_answered }) => sum + (+user_answered !== 2 ? 1 : 0), 0)
|
|
187
|
+
),
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
label: "خودسنجی ۱",
|
|
191
|
+
marks: dataset.questions.slice(216, 216 + 6).map((q) => +q.user_answered),
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
label: "خودسنجی ۲",
|
|
195
|
+
marks: dataset.questions.slice(222, 222 + 6).map((q) => +q.user_answered),
|
|
196
|
+
},
|
|
197
|
+
];
|
|
198
|
+
const itemObject = {};
|
|
199
|
+
let last = undefined;
|
|
200
|
+
const list = items
|
|
201
|
+
.map((item) => item.mark)
|
|
202
|
+
.sort((a, b) => b - a)
|
|
203
|
+
.filter((mark, i) => {
|
|
204
|
+
if (i <= 2) {
|
|
205
|
+
last = mark;
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
if (mark === last) {
|
|
209
|
+
return true;
|
|
210
|
+
} else {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
items.forEach((item) => (itemObject[item.label.eng.slice(0, -4)] = item));
|
|
215
|
+
const itemRadians = [
|
|
216
|
+
itemObject.artistic,
|
|
217
|
+
itemObject.social,
|
|
218
|
+
itemObject.enterprising,
|
|
219
|
+
itemObject.conventional,
|
|
220
|
+
itemObject.realistic,
|
|
221
|
+
itemObject.investigative,
|
|
222
|
+
].map((item, i) => {
|
|
223
|
+
const mark = ((item.mark ?? 0) * 207) / 56;
|
|
224
|
+
item.rad = pointsToCoordinates(mark - 14, i * 60);
|
|
225
|
+
item.bold = list.includes(item.mark);
|
|
226
|
+
item.percentageText = Math.floor(item.percentage * 100);
|
|
227
|
+
return item;
|
|
228
|
+
});
|
|
229
|
+
return [
|
|
230
|
+
{
|
|
231
|
+
items: [...items].sort((item1, item2) => item2.mark - item1.mark),
|
|
232
|
+
questionItems,
|
|
233
|
+
titleAppend: " - ۱",
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
itemRadians,
|
|
237
|
+
titleAppend: " - ۲",
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
items: [...items].reverse(),
|
|
241
|
+
reportMap,
|
|
242
|
+
titleAppend: " - ۳",
|
|
243
|
+
},
|
|
244
|
+
];
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function pointsToCoordinates(mark, angle) {
|
|
249
|
+
angle = (angle * Math.PI) / 180;
|
|
250
|
+
const start = [296 + 31 * Math.cos(angle), 261.5 + 31 * Math.sin(angle)];
|
|
251
|
+
const end = [start[0] + mark * Math.cos(angle), start[1] + mark * Math.sin(angle)];
|
|
252
|
+
const value = [end[0] + 12 * Math.cos(angle), end[1] + 12 * Math.sin(angle)];
|
|
253
|
+
return { start, end, value };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
module.exports = RIASEC9A;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const { Profile } = require("../Profile");
|
|
2
|
+
|
|
3
|
+
class RSI93 extends Profile {
|
|
4
|
+
static pages = 1;
|
|
5
|
+
|
|
6
|
+
// RSI93 — "تصور از خدا" (خسروی). Chart has two halves:
|
|
7
|
+
// • Left : two mirrored donut-ring gauges (pink = negative image, green = positive image).
|
|
8
|
+
// • Right : two horizontal bars (god_in_life, god_cares) — the two sub-factors whose
|
|
9
|
+
// sum is the positive-image score (per the designer).
|
|
10
|
+
// Maxes = items × 5 (scoring/RSI93.py → round(raw / (count·5), 2)):
|
|
11
|
+
// negative_image 6→30, positive_image 21→105, god_in_life 11→55, god_cares 10→50.
|
|
12
|
+
// Each factor exposes _raw + _percentage; we read raw for the "X از Y" fraction and the
|
|
13
|
+
// 0–1 percentage for the fill sweep + the "٪ NN" label (designer: "محاسبه با درصد").
|
|
14
|
+
labels = {
|
|
15
|
+
L1_1: { eng: "negative_image_raw", max: 30 },
|
|
16
|
+
L1_2: { eng: "negative_image_percentage" },
|
|
17
|
+
|
|
18
|
+
L2_1: { eng: "positive_image_raw", max: 105 },
|
|
19
|
+
L2_2: { eng: "positive_image_percentage" },
|
|
20
|
+
|
|
21
|
+
L3_1: { eng: "god_in_life_raw", max: 55, title: "حضور خدا در زندگی" },
|
|
22
|
+
L3_2: { eng: "god_in_life_percentage" },
|
|
23
|
+
|
|
24
|
+
L4_1: { eng: "god_cares_raw", max: 50, title: "مراقبت خداوند" },
|
|
25
|
+
L4_2: { eng: "god_cares_percentage" },
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
profileSpec = {
|
|
29
|
+
sample: {
|
|
30
|
+
name: "پرسشنامه تصور از خدا (خسروی)",
|
|
31
|
+
multiProfile: false,
|
|
32
|
+
questions: false,
|
|
33
|
+
defaultFields: true,
|
|
34
|
+
fields: [],
|
|
35
|
+
},
|
|
36
|
+
profile: {
|
|
37
|
+
get dimensions() {
|
|
38
|
+
return {
|
|
39
|
+
width: 740 + 2 * this.padding.x, // Chart layer 740 wide → 943 page
|
|
40
|
+
height: 318 + 2 * this.padding.y, // Chart layer 318 tall → 754 page
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
padding: {
|
|
44
|
+
x: 101.5, // (943 − 740) / 2
|
|
45
|
+
y: 218, // (754 − 318) / 2
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
labels: Object.values(this.labels),
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
constructor(dataset, options, config = {}) {
|
|
52
|
+
super();
|
|
53
|
+
this._init(dataset, options, config);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
_calcContext() {
|
|
57
|
+
const { dataset } = this;
|
|
58
|
+
const s = dataset.score;
|
|
59
|
+
|
|
60
|
+
const neg = packItem(s[0], s[1]); // negative image → left ring (pink)
|
|
61
|
+
const pos = packItem(s[2], s[3]); // positive image → right ring (green)
|
|
62
|
+
|
|
63
|
+
// Ring fill sweep. Both rings: 0 % at the bottom base (90°), 100 % at the top.
|
|
64
|
+
// • Left ring fills clockwise up the LEFT (increasing θ): zeta = π/2 + p·π (direction false).
|
|
65
|
+
// • Right ring fills counter-cw up the RIGHT (decreasing θ): zeta = π/2 − p·π (direction true).
|
|
66
|
+
neg.zeta = Math.PI / 2 + neg.p * Math.PI;
|
|
67
|
+
pos.zeta = Math.PI / 2 - pos.p * Math.PI;
|
|
68
|
+
|
|
69
|
+
const bars = [
|
|
70
|
+
packItem(s[4], s[5]), // god_in_life
|
|
71
|
+
packItem(s[6], s[7]), // god_cares
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
return [{ neg, pos, bars }];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Merge a factor's _raw and _percentage score entries into one drawing item.
|
|
79
|
+
function packItem(raw, percentage) {
|
|
80
|
+
return {
|
|
81
|
+
label: raw.label,
|
|
82
|
+
max: raw.label.max,
|
|
83
|
+
mark: raw.mark ?? 0,
|
|
84
|
+
percentage: Math.round((percentage.mark ?? 0) * 100),
|
|
85
|
+
p: percentage.mark ?? 0,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = RSI93;
|
package/src/samples/SASQ93.js
CHANGED
|
@@ -19,7 +19,7 @@ class SASQ93 extends Profile {
|
|
|
19
19
|
multiProfile: false /* Whether the sample has multiple profiles or not */,
|
|
20
20
|
questions: false /* Determines whether to get questions from inital dataset or not */,
|
|
21
21
|
defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
|
|
22
|
-
fields: [
|
|
22
|
+
fields: [] /* In case you want to get some additional fields and show in the profile */,
|
|
23
23
|
},
|
|
24
24
|
/* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
|
|
25
25
|
/* calculating its dimensions carefully is of great importance */
|
package/src/samples/SDCAQ93.js
CHANGED
|
@@ -23,7 +23,7 @@ class SDCAQ93 extends Profile {
|
|
|
23
23
|
multiProfile: false /* Whether the sample has multiple profiles or not */,
|
|
24
24
|
questions: false /* Determines whether to get questions from inital dataset or not */,
|
|
25
25
|
defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
|
|
26
|
-
fields: [
|
|
26
|
+
fields: [] /* In case you want to get some additional fields and show in the profile */,
|
|
27
27
|
},
|
|
28
28
|
/* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
|
|
29
29
|
/* calculating its dimensions carefully is of great importance */
|
package/src/samples/STAIY93.js
CHANGED
|
@@ -19,7 +19,7 @@ class STAIY93 extends Profile {
|
|
|
19
19
|
multiProfile: false /* Whether the sample has multiple profiles or not */,
|
|
20
20
|
questions: false /* Determines whether to get questions from inital dataset or not */,
|
|
21
21
|
defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
|
|
22
|
-
fields: [
|
|
22
|
+
fields: [] /* In case you want to get some additional fields and show in the profile */,
|
|
23
23
|
},
|
|
24
24
|
/* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
|
|
25
25
|
/* calculating its dimensions carefully is of great importance */
|
package/src/samples/WAQ93.js
CHANGED
|
@@ -25,7 +25,7 @@ class WAQ93 extends Profile {
|
|
|
25
25
|
multiProfile: false /* Whether the sample has multiple profiles or not */,
|
|
26
26
|
questions: false /* Determines whether to get questions from inital dataset or not */,
|
|
27
27
|
defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
|
|
28
|
-
fields: [
|
|
28
|
+
fields: [] /* In case you want to get some additional fields and show in the profile */,
|
|
29
29
|
},
|
|
30
30
|
/* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
|
|
31
31
|
/* calculating its dimensions carefully is of great importance */
|
package/src/samples/YBOCS93.js
CHANGED
|
@@ -398,7 +398,7 @@ class YBOCS93 extends Profile {
|
|
|
398
398
|
multiProfile: true /* Whether the sample has multiple profiles or not */,
|
|
399
399
|
questions: true /* Determines whether to get questions from inital dataset or not */,
|
|
400
400
|
defaultFields: true /* Determines whether to have default prerequisites in the profile or not */,
|
|
401
|
-
fields: [
|
|
401
|
+
fields: [] /* In case you want to get some additional fields and show in the profile */,
|
|
402
402
|
},
|
|
403
403
|
/* "profile" determines the dimensions of the drawn profile (to be used in svg tag viewbox) */
|
|
404
404
|
/* calculating its dimensions carefully is of great importance */
|
package/src/samples/YPI93.js
CHANGED
|
@@ -3,6 +3,10 @@ class YPI93 extends Profile {
|
|
|
3
3
|
// Number of pages
|
|
4
4
|
static pages = 2;
|
|
5
5
|
|
|
6
|
+
static partials = {
|
|
7
|
+
YPI93_factors: "samples/YPI93_factors.hbs",
|
|
8
|
+
};
|
|
9
|
+
|
|
6
10
|
// Labels of the sample
|
|
7
11
|
labels = {
|
|
8
12
|
L1_fs: { eng: "ab_father_score", group: 1},
|
|
@@ -347,4 +351,4 @@ const Items = {
|
|
|
347
351
|
60:f15,61:f15,62:f15,63:f15,64:f15,
|
|
348
352
|
65:f16,66:f16,67:f16,68:f16,
|
|
349
353
|
69:f17,70:f17,71:f17,72:f17
|
|
350
|
-
}
|
|
354
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<defs>
|
|
2
|
+
<linearGradient id="mcmGray" x1="0" y1="1" x2="0" y2="0">
|
|
3
|
+
<stop stop-color="#CBD5E1"/>
|
|
4
|
+
<stop offset="1" stop-color="#94A3B8"/>
|
|
5
|
+
</linearGradient>
|
|
6
|
+
<linearGradient id="mcmZinc" x1="0" y1="1" x2="0" y2="0">
|
|
7
|
+
<stop stop-color="#D4D4D8"/>
|
|
8
|
+
<stop offset="1" stop-color="#A1A1AA"/>
|
|
9
|
+
</linearGradient>
|
|
10
|
+
<linearGradient id="mcmYellow" x1="0" y1="1" x2="0" y2="0">
|
|
11
|
+
<stop stop-color="#FEF08A"/>
|
|
12
|
+
<stop offset="1" stop-color="#EAB308"/>
|
|
13
|
+
</linearGradient>
|
|
14
|
+
<linearGradient id="mcmOrange" x1="0" y1="1" x2="0" y2="0">
|
|
15
|
+
<stop stop-color="#FDBA74"/>
|
|
16
|
+
<stop offset="1" stop-color="#EA580C"/>
|
|
17
|
+
</linearGradient>
|
|
18
|
+
<linearGradient id="mcmRose" x1="0" y1="1" x2="0" y2="0">
|
|
19
|
+
<stop stop-color="#FDA4AF"/>
|
|
20
|
+
<stop offset="1" stop-color="#E11D48"/>
|
|
21
|
+
</linearGradient>
|
|
22
|
+
<filter id="mcmFacetBaseline" x="24" y="358" width="838" height="7" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
23
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
24
|
+
<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"/>
|
|
25
|
+
<feOffset dx="1"/>
|
|
26
|
+
<feGaussianBlur stdDeviation="1.5"/>
|
|
27
|
+
<feComposite in2="hardAlpha" operator="out"/>
|
|
28
|
+
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
|
|
29
|
+
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1"/>
|
|
30
|
+
<feBlend mode="normal" in="SourceGraphic" in2="effect1" result="shape"/>
|
|
31
|
+
</filter>
|
|
32
|
+
</defs>
|
|
33
|
+
|
|
34
|
+
<g transform="translate({{padding.x}}, {{padding.y}})">
|
|
35
|
+
{{#each groups as |group|}}
|
|
36
|
+
{{#each group.facets as |item|}}
|
|
37
|
+
<g transform="translate({{item.x}}, 61)">
|
|
38
|
+
{{bar 16 300 (object tl=2 bl=0 tr=2 br=0) (toRad 0) fill=item.theme.track}}
|
|
39
|
+
</g>
|
|
40
|
+
{{/each}}
|
|
41
|
+
{{/each}}
|
|
42
|
+
|
|
43
|
+
<line x1="26.5" y1="61.5" x2="857.5" y2="61.5" stroke="#E5E7EB" stroke-linecap="round" stroke-dasharray="6 6"/>
|
|
44
|
+
<line x1="26.5" y1="136.5" x2="857.5" y2="136.5" stroke="#D1D5DB" stroke-linecap="round"/>
|
|
45
|
+
<line x1="26.5" y1="211.5" x2="857.5" y2="211.5" stroke="#E5E7EB" stroke-linecap="round" stroke-dasharray="6 6"/>
|
|
46
|
+
<line x1="26.5" y1="286.5" x2="857.5" y2="286.5" stroke="#E5E7EB" stroke-linecap="round" stroke-dasharray="6 6"/>
|
|
47
|
+
|
|
48
|
+
<text x="10" y="70.5" transform="rotate(-90 10 70.5)" direction="ltr" font-size="12" fill="#9CA3AF" text-anchor="middle">100</text>
|
|
49
|
+
<text x="10" y="136.5" transform="rotate(-90 10 136.5)" direction="ltr" font-size="12" font-weight="500" fill="#6B7280" text-anchor="middle">75</text>
|
|
50
|
+
<text x="10" y="211.5" transform="rotate(-90 10 211.5)" direction="ltr" font-size="12" fill="#9CA3AF" text-anchor="middle">50</text>
|
|
51
|
+
<text x="10" y="286.5" transform="rotate(-90 10 286.5)" direction="ltr" font-size="12" fill="#9CA3AF" text-anchor="middle">25</text>
|
|
52
|
+
<text x="10" y="361.5" transform="rotate(-90 10 361.5)" direction="ltr" font-size="12" fill="#9CA3AF" text-anchor="middle">BR</text>
|
|
53
|
+
<text x="10" y="0" transform="rotate(-90 10 0)" font-size="12" fill="#9CA3AF" text-anchor="start">نمره خام</text>
|
|
54
|
+
<path d="M3 48H10M7 51L10 48L7 45" fill="none" stroke="#9CA3AF" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"/>
|
|
55
|
+
|
|
56
|
+
{{#each groups as |group|}}
|
|
57
|
+
{{#each group.facets as |item|}}
|
|
58
|
+
{{#if item.barHeight}}
|
|
59
|
+
<g transform="translate({{item.x}}, {{item.barTop}})" fill="url(#{{item.theme.gradient}})">
|
|
60
|
+
{{bar 16 item.barHeight (object tl=2 bl=0 tr=2 br=0) (toRad 0)}}
|
|
61
|
+
</g>
|
|
62
|
+
{{/if}}
|
|
63
|
+
<text x="{{item.center}}" y="{{item.scoreY}}" transform="rotate(-90 {{item.center}} {{item.scoreY}})" direction="ltr" font-size="15" font-weight="{{ternary item.inside '600' '400'}}" fill="{{ternary item.inside 'white' item.theme.dark}}" text-anchor="{{item.scoreAnchor}}" dy=".35em">{{item.br}}</text>
|
|
64
|
+
<rect x="{{item.x}}" y="16" width="16" height="36" rx="2" fill="{{item.theme.track}}"/>
|
|
65
|
+
<text x="{{item.center}}" y="34" transform="rotate(-90 {{item.center}} 34)" direction="ltr" font-size="13" fill="{{item.theme.dark}}" text-anchor="middle" dy=".35em">{{item.raw}}</text>
|
|
66
|
+
{{!--
|
|
67
|
+
The code is centered in an invisible 32 × 16 box at y=366..398.
|
|
68
|
+
Gaps: chart baseline → code box = 4, code box → dash = 8,
|
|
69
|
+
dash → Persian title = 8.
|
|
70
|
+
--}}
|
|
71
|
+
<text class="eng-font" x="{{item.center}}" y="382" transform="rotate(-90 {{item.center}} 382)" direction="ltr" font-size="13" font-weight="{{ternary item.inside '600' '400'}}" fill="{{item.theme.text}}" text-anchor="middle" dy=".35em">{{item.code}}</text>
|
|
72
|
+
<text x="{{item.center}}" y="408.5" transform="rotate(-90 {{item.center}} 408.5)" font-size="13" font-weight="{{ternary item.inside '600' '300'}}" fill="{{item.theme.text}}" text-anchor="middle" dy=".35em">-</text>
|
|
73
|
+
<text x="{{item.center}}" y="419.6" transform="rotate(-90 {{item.center}} 419.6)" font-size="13" font-weight="{{ternary item.inside '600' '400'}}" fill="{{item.theme.text}}" text-anchor="start" dy=".35em">{{item.fa}}</text>
|
|
74
|
+
{{/each}}
|
|
75
|
+
|
|
76
|
+
<rect x="{{group.cardX}}" y="615.5" width="79" height="47" rx="4" fill="{{group.theme.card}}" stroke="{{group.theme.stroke}}"/>
|
|
77
|
+
{{#if (boolean group.key "===" "6b")}}
|
|
78
|
+
<g transform="rotate(180 {{math group.cardX '+' 39.5}} 639)">
|
|
79
|
+
<text x="{{math group.cardX '+' 39.5}}" y="631" dy=".3em" font-size="13" font-weight="500" fill="{{group.theme.dark}}" text-anchor="middle">دیگرآزار</text>
|
|
80
|
+
<text x="{{math group.cardX '+' 39.5}}" y="647" dy=".3em" font-size="13" font-weight="500" fill="{{group.theme.dark}}" text-anchor="middle">(سادیستیک)</text>
|
|
81
|
+
</g>
|
|
82
|
+
{{else}}
|
|
83
|
+
<text x="{{math group.cardX '+' 39.5}}" y="639" transform="rotate(180 {{math group.cardX '+' 39.5}} 639)" dy=".3em" font-size="13" font-weight="500" fill="{{group.theme.dark}}" text-anchor="middle">{{group.fa}}</text>
|
|
84
|
+
{{/if}}
|
|
85
|
+
<g transform="translate({{math group.cardX '+' 3.5}}, 663)">
|
|
86
|
+
{{bar 72 36 (object tl=0 tr=0 bl=2 br=2) (toRad 0) fill=group.theme.card}}
|
|
87
|
+
</g>
|
|
88
|
+
<line x1="{{math group.cardX '+' 39.5}}" y1="666" x2="{{math group.cardX '+' 39.5}}" y2="696" stroke="{{group.theme.divider}}"/>
|
|
89
|
+
<text class="eng-font" x="{{math group.cardX '+' 19.5}}" y="681" transform="rotate(-90 {{math group.cardX '+' 19.5}} 681)" direction="ltr" font-size="13" font-weight="500" fill="{{group.theme.cardText}}" text-anchor="middle" dy=".35em">{{group.code}}</text>
|
|
90
|
+
<text x="{{math group.cardX '+' 59.5}}" y="681" transform="rotate(-90 {{math group.cardX '+' 59.5}} 681)" direction="ltr" font-size="13" font-weight="500" fill="{{group.theme.cardText}}" text-anchor="middle" dy=".35em">{{group.br}}</text>
|
|
91
|
+
{{/each}}
|
|
92
|
+
|
|
93
|
+
<g opacity="0.5" filter="url(#mcmFacetBaseline)">
|
|
94
|
+
<line x1="26.5" y1="361.5" x2="857.5" y2="361.5" stroke="white" stroke-linecap="round"/>
|
|
95
|
+
</g>
|
|
96
|
+
</g>
|