API and Data Contract
A proposal, not a decision. Every entity and relationship below is open to challenge; the open decisions are listed at the end.
Version 0.3, 6 September 2026 (0.1 and 0.2 earlier the same day; changes listed at the end). The single agreement between the engine track (backend, solver) and the experience track (UI, flows). Both build against this document. Any change to a shape or endpoint is made here first, by whoever needs it, with a version bump, and the other track is told.
Overview
The contract has two halves: the JSON shapes of the domain objects, taken from the domain model proposal, and the HTTP endpoints through which a client reads and writes them and asks for a timetable. The engine implements the endpoints; the experience track stubs them with the same shapes until integration.
Summary
- Every object has a string
id, a displayname, and where a Hebrew display name exists,nameHe. Times are ISO 8601 strings. Enumerations are lowercase strings. - A School owns everything else. All collection endpoints are scoped by school.
- The unit of scheduling is the Event. A Timetable is a versioned set of Assignments of events to slots, with Violations against Constraints.
- Solving is asynchronous:
POST /solvereturns a Job; the client polls it and reads the resulting timetable. Repair is the same call withpinnedassignments and abasedOntimetable. - Errors are JSON
{ "error": { "code": string, "message": string, "details"?: object } }with HTTP 4xx or 5xx.
Bottom line
Version 0.1 covers what Mevo Hagalil needs: staff with availability, classes and student groups, subjects, a curriculum, events with staff slots, constraints traceable to requirement IDs, and timetables with violations and pinning. Rooms and students are present in the shapes but optional everywhere.
Detailed explanation
Shapes
{
"School": {
"id": "mevo-hagalil", "name": "Mevo Hagalil", "nameHe": "מבוא הגליל",
"sector": "state", "stage": "primary",
"timeGrid": {
"days": ["sun", "mon", "tue", "wed", "thu"],
"periodsPerDay": {"sun": 7, "mon": 7, "tue": 5, "wed": 7, "thu": 7},
"longDayPeriod": 7,
"clockTimes": [{"period": 1, "start": "08:00", "end": "08:45"}],
"breaks": [{"afterPeriod": 2, "start": "09:25", "end": "09:55", "kind": "break", "name": "Breakfast and break", "nameHe": "ארוחת בוקר והפסקה"}]
}
},
"RoomType": {"id": "science", "schoolId": "mevo-hagalil", "name": "Science room", "nameHe": "חדר מדעים"},
"Room": {"id": "r-science", "schoolId": "mevo-hagalil", "roomTypeId": "science", "name": "Science room", "nameHe": "חדר מדעים", "ownerStaffIds": ["s-keren-s", "s-shirly"]},
"Grade": {"id": "g3", "schoolId": "mevo-hagalil", "level": 3, "name": "Grade 3", "nameHe": "מחזור ג'"},
"Class": {"id": "c-3-nesher", "schoolId": "mevo-hagalil", "gradeId": "g3", "name": "3 Nesher", "nameHe": "ג' נשר", "homeroomStaffId": "s-idit"},
"StudentGroup": {
"id": "sg-3-nesher", "schoolId": "mevo-hagalil",
"kind": "class",
"classIds": ["c-3-nesher"],
"name": "3 Nesher", "nameHe": "ג' נשר",
"studentIds": []
},
"Staff": {
"id": "s-idit", "schoolId": "mevo-hagalil",
"name": "Idit Tamir", "nameHe": "תמיר עידית", "shortNameHe": "עידית",
"role": "teacher",
"contract": "ofek-hadash",
"hours": {"frontal": 23, "individual": 4, "staying": 9, "derived": true},
"subjectIds": ["math", "hebrew"],
"homeroomClassId": "c-3-nesher",
"availability": [
{"day": "tue", "period": null, "state": "unavailable", "reason": "part-time"},
{"day": "mon", "period": 5, "state": "unavailable", "reason": "meeting: grade 3 team"}
]
},
"Subject": {"id": "math", "schoolId": "mevo-hagalil", "name": "Mathematics", "nameHe": "חשבון", "isCore": true, "roomTypeId": null},
"CurriculumLine": {
"id": "cl-g3-math", "schoolId": "mevo-hagalil", "gradeId": "g3", "subjectId": "math",
"weeklyPeriods": 5, "pattern": [1, 1, 1, 1, 1],
"coTeaching": {"required": true, "withHomeroom": true}
},
"Event": {
"id": "ev-3-nesher-math-1", "schoolId": "mevo-hagalil",
"kind": "lesson",
"subjectId": "math",
"duration": 1,
"studentGroupIds": ["sg-3-nesher"],
"staffSlots": [
{"role": "lead", "staffId": "s-idit"},
{"role": "co", "staffId": null, "subjectId": "math"}
],
"roomTypeId": null,
"curriculumLineId": "cl-g3-math",
"eventGroupId": "eg-3-nesher-math",
"fixedAt": null,
"tags": []
},
"EventGroup": {"id": "eg-3-nesher-math", "schoolId": "mevo-hagalil", "kind": "same-course", "eventIds": ["ev-3-nesher-math-1"]},
"Constraint": {
"id": "k-r06", "schoolId": "mevo-hagalil",
"type": "homeroom-starts-first-period",
"enabled": true,
"hard": false, "weight": 10,
"params": {"minDays": 3},
"appliesTo": {"staffIds": [], "classIds": [], "subjectIds": [], "all": true},
"implements": ["R-06"],
"name": "Homeroom starts the day", "nameHe": "מחנכת פותחת את היום"
},
"Timetable": {
"id": "tt-2026-09-03", "schoolId": "mevo-hagalil",
"version": 3, "status": "draft",
"basedOnId": "tt-2026-08-30",
"createdAt": "2026-09-06T10:00:00Z",
"score": {"hard": 0, "soft": 42},
"assignments": [
{"eventId": "ev-3-nesher-math-1", "slots": [{"day": "sun", "period": 2}], "roomId": null, "staffIds": ["s-idit", "s-sapir-h"], "pinned": false}
],
"violations": [
{"constraintId": "k-r06", "cost": 10, "entityIds": ["s-mor"], "eventIds": [], "slots": [{"day": "tue", "period": 1}], "message": "Mor starts at period 1 on 2 days; the rule asks for 3.", "messageHe": "מור מתחילה בשיעור 1 ב-2 ימים; הכלל דורש 3."}
]
},
"Job": {"id": "job-123", "kind": "solve", "status": "running", "progress": {"phase": "improving", "elapsedSeconds": 12, "hard": 0, "soft": 57}, "resultTimetableId": null, "error": null}
}
Enumerations:
StudentGroup.kind:class,half,level,cross,cohort.Staff.role:teacher,assistant,soldier,external.Staff.contract:ofek-hadash,oz-latmura,other.Staff.hours.derivedmarks estimated counts.Availability.reasonstarting withmeeting:counts as busy time for the no-gaps rule.Availability.state:unavailable,prefer-not.period: nullmeans the whole day.Event.kind:lesson,activity,meeting,individual,staying.Event.fixedAt:nullor{"day": "sun", "period": 4}for the first slot of the event.StaffSlot.role:lead,co,assistant,soldier. A slot withstaffId: nullis filled by the solver from staff who teachsubjectId(or any staff whensubjectIdis null).EventGroup.kind:same-course(spread across the week),linked(must be simultaneous).Timetable.status:draft,published,archived.Job.status:queued,running,done,failed,cancelled.
Constraint types, version 0.3
Each type has fixed params. The engine validates them. The list grows as requirements are confirmed.
| type | params | implements |
|---|---|---|
no-clash | none; always hard. Half groups of the same class do not clash with each other; open slots (staffId: null) never clash | structural |
availability | none; reads Staff.availability | R-09, R-10, S-05 |
no-gaps | edgesAreGaps: false, tuesdayStayingDeduction: 2, lunchDuties: 2, lunchDutiesByStaff: {staffId: n}; budget = individual + staying − deductions − non-frontal hours already placed | R-05, S-11, S-12 |
homeroom-starts-first-period | minDays, ownClass: true | R-06 |
ends-long-day | days, comparison, minWorkingDays: 4, perStaffDays: {staffId: n}, partTimeRule: "proportional" or "exempt" | R-07 |
subject-per-day | subjectId, min, max (null = no max), halvesCountOnce: true | R-08 |
block-at-periods | eventGroupId, firstPeriod, lastPeriod, excludeDays | R-11 |
spread-over-days | eventGroupIds, distinctDays: bool | R-11 |
double-period | curriculumLineId | R-12 |
avoid-last-period | subjectIds, period (7 for Mevo Hagalil) | R-14 |
fixed-time | reads Event.fixedAt; always hard | S-05, S-06, S-07, S-15 |
room-shared-owners | roomId, maxSimultaneous: 1, exemptCoTeaching: bool; soft | S-13 |
room-owner-whole-class | roomId; hard: when one owner co-teaches, the other owner's simultaneous lesson must be a whole class | S-13 |
Endpoints
Base path /api/v1. All collections support GET (list), POST (create), and GET, PUT, DELETE on /{id}. Lists return {"items": [...], "total": n}.
| Path | Notes |
|---|---|
/schools | |
/schools/{schoolId}/grades | |
/schools/{schoolId}/classes | |
/schools/{schoolId}/student-groups | |
/schools/{schoolId}/staff | availability is embedded |
/schools/{schoolId}/subjects | |
/schools/{schoolId}/curriculum | CurriculumLine |
/schools/{schoolId}/room-types, /schools/{schoolId}/rooms | Room has ownerStaffIds |
/schools/{schoolId}/events | POST /generate derives events from the curriculum for every class; existing generated events are replaced, fixed and tagged ones kept |
/schools/{schoolId}/event-groups | |
/schools/{schoolId}/constraints | GET /types lists constraint types and their params |
/schools/{schoolId}/timetables | GET /{id} includes assignments and violations; POST /{id}/publish; POST /{id}/fork creates a new draft based on it; POST /{id}/pin with {"eventIds": [...], "pinned": true}. A published timetable is immutable: PUT on it returns 409; fork first. |
/schools/{schoolId}/solve | body {"basedOnId"?: string, "timeLimitSeconds"?: number, "pinnedEventIds"?: [...]}; returns a Job |
/schools/{schoolId}/score | body: a Timetable; returns score and violations without solving |
/jobs/{jobId} | DELETE cancels |
/schools/{schoolId}/import/tiktak | multipart upload of the Tik-Tak export; returns created objects and a draft timetable |
/schools/{schoolId}/export/xhstt | XHSTT XML of the school and its published timetable |
Conventions for the stub
The experience track ships a stub that implements every endpoint above in memory, seeded with a fixture derived from Mevo Hagalil (data/mevo-hagalil/). POST /solve in the stub returns a Job that moves queued, running, done over a few seconds and produces a timetable equal to the fixture with a handful of synthetic violations, so the review and repair flows can be designed against realistic output.
Open items
- Room assignment is out of scope in 0.1;
roomIdandroomTypeIdare accepted and ignored. - Non-frontal hours (individual, staying) are events of those kinds only if Q-03 says they must be placed; otherwise they are counts on Staff.
- Authentication and multi-user editing are not in 0.1.
Changes in 0.2
Requested by the experience track after building the prototype; the engine track adopts them in its next iteration.
Constraint.enabled(boolean, default true): switch a rule off without deleting it.Constraint.implementsis an array of requirement IDs, since one constraint type can cover several (availability covers R-09, R-10, S-05).Violation.eventIdsandViolation.slots(optional): the events and grid cells involved, so the UI can focus them.entityIdsremains for people and classes.POST /timetables/{id}/forkand the rule that a published timetable is immutable.
Changes in 0.3
From Vegman's answers of 6 September (requirements v0.3) and both tracks' implementations.
TimeGrid.breaks[]withafterPeriod,start,end,kind,name,nameHe(S-16).RoomTypeandRoomwithownerStaffIds, plus their endpoints (S-13). Room assignment itself is still out of scope; rooms carry sharing rules only.Staff.hours.derivedfor estimated counts while the teacher table is confidential (Q-02);Staff.rolegainsexternal(S-15).- New constraint types
room-shared-ownersandroom-owner-whole-class; new parameters onno-gaps,ends-long-day,subject-per-day,avoid-last-period,homeroom-starts-first-periodas listed in the table. Availability.reasonvalues starting withmeeting:count as busy for the no-gaps rule (S-05, S-11).- Open staff slots (
staffId: null) are legal in a published timetable and never produce clashes (S-14).
חוזה API ונתונים
הצעה, לא החלטה. כל ישות וקשר להלן פתוחים לערעור; ההחלטות הפתוחות מפורטות בסוף.
גרסה 0.2, 6 בספטמבר 2026 (0.1 מוקדם יותר באותו יום; השינויים מפורטים בסוף). ההסכם היחיד בין מסלול המנוע (צד שרת, פותר) לבין מסלול החוויה (ממשק משתמש, תהליכים). שני המסלולים בונים על פי מסמך זה. כל שינוי בצורה או בנקודת קצה נעשה כאן תחילה, על ידי מי שזקוק לו, עם העלאת גרסה, והמסלול השני מעודכן.
> גרסה 0.3 (6 בספטמבר 2026): נוספו הפסקות ברשת הזמן, חדרים עם בעלים, סימון שעות משוערות, ושני סוגי אילוצי חדרים. הפירוט המלא בגרסה האנגלית, בסעיף "Changes in 0.3".
סקירה
לחוזה שני חצאים: צורות ה-JSON של אובייקטי התחום, הלקוחות מהצעת מודל התחום, ונקודות הקצה של HTTP שדרכן לקוח קורא וכותב אותן ומבקש מערכת שעות. המנוע מממש את נקודות הקצה; מסלול החוויה מדמה אותן (stub) באותן צורות עד לאינטגרציה.
תקציר
- לכל אובייקט יש
idמחרוזתי,nameלתצוגה, ובמקום שקיים שם תצוגה בעברית,nameHe. זמנים הם מחרוזות ISO 8601. ערכי ספירה (enumerations) הם מחרוזות באותיות קטנות. - School (בית ספר) הוא הבעלים של כל השאר. כל נקודות הקצה של אוספים ממוקדות לפי בית ספר.
- יחידת התזמון היא Event (אירוע). Timetable (מערכת שעות) היא קבוצה מגורסת של Assignments (שיבוצים) של אירועים למשבצות, עם Violations (הפרות) כנגד Constraints (אילוצים).
- הפתרון אסינכרוני:
POST /solveמחזיר Job (משימה); הלקוח סוקר (polls) אותה וקורא את מערכת השעות שהתקבלה. תיקון הוא אותה קריאה עם שיבוציםpinnedומערכת שעותbasedOn. - שגיאות הן JSON
{ "error": { "code": string, "message": string, "details"?: object } }עם HTTP 4xx או 5xx.
שורה תחתונה
גרסה 0.1 מכסה את מה שמבוא הגליל צריך: צוות עם זמינות, כיתות וקבוצות תלמידים, מקצועות, תוכנית לימודים, אירועים עם משבצות צוות, אילוצים הניתנים למעקב אל מזהי דרישות, ומערכות שעות עם הפרות ונעיצה. חדרים ותלמידים קיימים בצורות אך אופציונליים בכל מקום.
הסבר מפורט
צורות
{
"School": {
"id": "mevo-hagalil", "name": "Mevo Hagalil", "nameHe": "מבוא הגליל",
"sector": "state", "stage": "primary",
"timeGrid": {
"days": ["sun", "mon", "tue", "wed", "thu"],
"periodsPerDay": {"sun": 7, "mon": 7, "tue": 5, "wed": 7, "thu": 7},
"longDayPeriod": 7,
"clockTimes": [{"period": 1, "start": "08:00", "end": "08:45"}]
}
},
"Grade": {"id": "g3", "schoolId": "mevo-hagalil", "level": 3, "name": "Grade 3", "nameHe": "מחזור ג'"},
"Class": {"id": "c-3-nesher", "schoolId": "mevo-hagalil", "gradeId": "g3", "name": "3 Nesher", "nameHe": "ג' נשר", "homeroomStaffId": "s-idit"},
"StudentGroup": {
"id": "sg-3-nesher", "schoolId": "mevo-hagalil",
"kind": "class",
"classIds": ["c-3-nesher"],
"name": "3 Nesher", "nameHe": "ג' נשר",
"studentIds": []
},
"Staff": {
"id": "s-idit", "schoolId": "mevo-hagalil",
"name": "Idit Tamir", "nameHe": "תמיר עידית", "shortNameHe": "עידית",
"role": "teacher",
"contract": "ofek-hadash",
"hours": {"frontal": 23, "individual": 4, "staying": 9},
"subjectIds": ["math", "hebrew"],
"homeroomClassId": "c-3-nesher",
"availability": [
{"day": "tue", "period": null, "state": "unavailable", "reason": "part-time"},
{"day": "mon", "period": 5, "state": "unavailable", "reason": "meeting: grade 3 team"}
]
},
"Subject": {"id": "math", "schoolId": "mevo-hagalil", "name": "Mathematics", "nameHe": "חשבון", "isCore": true, "roomTypeId": null},
"CurriculumLine": {
"id": "cl-g3-math", "schoolId": "mevo-hagalil", "gradeId": "g3", "subjectId": "math",
"weeklyPeriods": 5, "pattern": [1, 1, 1, 1, 1],
"coTeaching": {"required": true, "withHomeroom": true}
},
"Event": {
"id": "ev-3-nesher-math-1", "schoolId": "mevo-hagalil",
"kind": "lesson",
"subjectId": "math",
"duration": 1,
"studentGroupIds": ["sg-3-nesher"],
"staffSlots": [
{"role": "lead", "staffId": "s-idit"},
{"role": "co", "staffId": null, "subjectId": "math"}
],
"roomTypeId": null,
"curriculumLineId": "cl-g3-math",
"eventGroupId": "eg-3-nesher-math",
"fixedAt": null,
"tags": []
},
"EventGroup": {"id": "eg-3-nesher-math", "schoolId": "mevo-hagalil", "kind": "same-course", "eventIds": ["ev-3-nesher-math-1"]},
"Constraint": {
"id": "k-r06", "schoolId": "mevo-hagalil",
"type": "homeroom-starts-first-period",
"enabled": true,
"hard": false, "weight": 10,
"params": {"minDays": 3},
"appliesTo": {"staffIds": [], "classIds": [], "subjectIds": [], "all": true},
"implements": ["R-06"],
"name": "Homeroom starts the day", "nameHe": "מחנכת פותחת את היום"
},
"Timetable": {
"id": "tt-2026-09-03", "schoolId": "mevo-hagalil",
"version": 3, "status": "draft",
"basedOnId": "tt-2026-08-30",
"createdAt": "2026-09-06T10:00:00Z",
"score": {"hard": 0, "soft": 42},
"assignments": [
{"eventId": "ev-3-nesher-math-1", "slots": [{"day": "sun", "period": 2}], "roomId": null, "staffIds": ["s-idit", "s-sapir-h"], "pinned": false}
],
"violations": [
{"constraintId": "k-r06", "cost": 10, "entityIds": ["s-mor"], "eventIds": [], "slots": [{"day": "tue", "period": 1}], "message": "Mor starts at period 1 on 2 days; the rule asks for 3.", "messageHe": "מור מתחילה בשיעור 1 ב-2 ימים; הכלל דורש 3."}
]
},
"Job": {"id": "job-123", "kind": "solve", "status": "running", "progress": {"phase": "improving", "elapsedSeconds": 12, "hard": 0, "soft": 57}, "resultTimetableId": null, "error": null}
}
ערכי ספירה:
StudentGroup.kind:class,half,level,cross,cohort.Staff.role:teacher,assistant,soldier.Staff.contract:ofek-hadash,oz-latmura,other.Availability.state:unavailable,prefer-not.period: nullפירושו היום כולו.Event.kind:lesson,activity,meeting,individual,staying.Event.fixedAt:nullאו{"day": "sun", "period": 4}עבור המשבצת הראשונה של האירוע.StaffSlot.role:lead,co,assistant,soldier. משבצת עםstaffId: nullממולאת על ידי הפותר מתוך אנשי צוות המלמדים אתsubjectId(או כל איש צוות כאשרsubjectIdהוא null).EventGroup.kind:same-course(מפוזר לאורך השבוע),linked(חייבים להתקיים בו-זמנית).Timetable.status:draft,published,archived.Job.status:queued,running,done,failed,cancelled.
סוגי אילוצים, גרסה 0.1
לכל סוג יש params קבועים. המנוע מאמת אותם. הרשימה גדלה ככל שדרישות מאושרות.
| type | params | implements |
|---|---|---|
no-clash | none; always hard | מבני |
availability | none; reads Staff.availability | R-09, R-10, S-05 |
no-gaps | countNonFrontalAsBusy: bool | R-05 |
homeroom-starts-first-period | minDays | R-06 |
ends-long-day | days, comparison: "exact" or "min" or "max" | R-07 |
subject-per-day | subjectId, min, max | R-08 |
block-at-periods | eventGroupId, firstPeriod, lastPeriod, excludeDays | R-11 |
spread-over-days | eventGroupIds, distinctDays: bool | R-11 |
double-period | curriculumLineId | R-12 |
avoid-last-period | subjectIds | R-14 |
fixed-time | reads Event.fixedAt; always hard | S-05, S-06, S-07 |
נקודות קצה
נתיב בסיס /api/v1. כל האוספים תומכים ב-GET (רשימה), POST (יצירה), וב-GET, PUT, DELETE על /{id}. רשימות מחזירות {"items": [...], "total": n}.
| נתיב | הערות |
|---|---|
/schools | |
/schools/{schoolId}/grades | |
/schools/{schoolId}/classes | |
/schools/{schoolId}/student-groups | |
/schools/{schoolId}/staff | הזמינות מוטמעת בתוך האובייקט |
/schools/{schoolId}/subjects | |
/schools/{schoolId}/curriculum | CurriculumLine |
/schools/{schoolId}/events | POST /generate גוזר אירועים מתוכנית הלימודים עבור כל כיתה; אירועים שנוצרו קודם לכן מוחלפים, אירועים קבועים ומתויגים נשמרים |
/schools/{schoolId}/event-groups | |
/schools/{schoolId}/constraints | GET /types מפרט את סוגי האילוצים ואת הפרמטרים שלהם |
/schools/{schoolId}/timetables | GET /{id} כולל שיבוצים והפרות; POST /{id}/publish; POST /{id}/fork יוצר טיוטה חדשה המבוססת עליה; POST /{id}/pin עם {"eventIds": [...], "pinned": true}. מערכת שעות שפורסמה אינה ניתנת לשינוי: PUT עליה מחזיר 409; יש לבצע fork תחילה. |
/schools/{schoolId}/solve | גוף {"basedOnId"?: string, "timeLimitSeconds"?: number, "pinnedEventIds"?: [...]}; מחזיר Job |
/schools/{schoolId}/score | גוף: Timetable; מחזיר score ו-violations ללא פתרון |
/jobs/{jobId} | DELETE מבטל |
/schools/{schoolId}/import/tiktak | העלאת multipart של ייצוא תיק-תק; מחזיר את האובייקטים שנוצרו ומערכת שעות טיוטה |
/schools/{schoolId}/export/xhstt | XML בתקן XHSTT של בית הספר ומערכת השעות שפורסמה שלו |
מוסכמות לסטאב
מסלול החוויה מספק סטאב המממש בזיכרון כל נקודת קצה שלעיל, מאותחל בנתוני דוגמה (fixture) הנגזרים ממבוא הגליל (data/mevo-hagalil/). POST /solve בסטאב מחזיר Job העובר בין queued, running, done במשך כמה שניות ומפיק מערכת שעות זהה לנתוני הדוגמה עם קומץ הפרות סינתטיות, כך שניתן לעצב את תהליכי הסקירה והתיקון מול פלט מציאותי.
פריטים פתוחים
- שיבוץ חדרים מחוץ לתחום ב-0.1;
roomIdו-roomTypeIdמתקבלים ומתעלמים מהם. - שעות לא-פרונטליות (פרטניות, שהייה) הן אירועים מסוגים אלה רק אם Q-03 קובע שיש למקם אותן; אחרת הן ספירות על Staff.
- אימות ועריכה מרובת משתמשים אינם כלולים ב-0.1.
שינויים ב-0.2
התבקשו על ידי מסלול החוויה לאחר בניית אב-הטיפוס; מסלול המנוע מאמץ אותם באיטרציה הבאה שלו.
Constraint.enabled(בוליאני, ברירת מחדל true): כיבוי כלל בלי למחוק אותו.Constraint.implementsהוא מערך של מזהי דרישות, מכיוון שסוג אילוץ אחד יכול לכסות כמה (availability מכסה את R-09, R-10, S-05).Violation.eventIdsו-Violation.slots(אופציונליים): האירועים ותאי הרשת המעורבים, כדי שממשק המשתמש יוכל למקד אותם.entityIdsנשאר עבור אנשים וכיתות.POST /timetables/{id}/forkוהכלל שמערכת שעות שפורסמה אינה ניתנת לשינוי.