@juki-team/commons 0.1.43 → 0.1.46

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 (65) hide show
  1. package/dist/cjs/index.cjs +514 -546
  2. package/dist/esm/index.js +416 -491
  3. package/dist/types/constants/entity.d.ts +3 -3
  4. package/dist/types/constants/index.d.ts +1 -1
  5. package/dist/types/constants/organization.d.ts +9 -0
  6. package/dist/types/constants/websocket.d.ts +18 -22
  7. package/dist/types/dto/class.d.ts +34 -34
  8. package/dist/types/dto/code.d.ts +1 -1
  9. package/dist/types/dto/comments.d.ts +9 -9
  10. package/dist/types/dto/contest.d.ts +46 -42
  11. package/dist/types/dto/course.d.ts +13 -13
  12. package/dist/types/dto/entity.d.ts +30 -25
  13. package/dist/types/dto/excalidraw.d.ts +7 -7
  14. package/dist/types/dto/file.d.ts +10 -15
  15. package/dist/types/dto/image.d.ts +2 -2
  16. package/dist/types/dto/index.d.ts +1 -1
  17. package/dist/types/dto/judge.d.ts +5 -5
  18. package/dist/types/dto/markdown.d.ts +7 -7
  19. package/dist/types/dto/mermaid.d.ts +7 -7
  20. package/dist/types/dto/{company.d.ts → organization.d.ts} +16 -16
  21. package/dist/types/dto/problem.d.ts +22 -22
  22. package/dist/types/dto/scoreboard.d.ts +8 -18
  23. package/dist/types/dto/session.d.ts +9 -9
  24. package/dist/types/dto/socket.d.ts +76 -125
  25. package/dist/types/dto/statistics.d.ts +7 -7
  26. package/dist/types/dto/submission.d.ts +22 -22
  27. package/dist/types/dto/system.d.ts +7 -82
  28. package/dist/types/dto/url.d.ts +1 -1
  29. package/dist/types/dto/user.d.ts +22 -22
  30. package/dist/types/dto/virtual-user.d.ts +3 -25
  31. package/dist/types/dto/worksheet-submissions.d.ts +22 -22
  32. package/dist/types/dto/worksheet.d.ts +12 -12
  33. package/dist/types/helpers/class.d.ts +4 -4
  34. package/dist/types/helpers/comments.d.ts +1 -1
  35. package/dist/types/helpers/contest.d.ts +4 -4
  36. package/dist/types/helpers/date.d.ts +68 -0
  37. package/dist/types/helpers/document.d.ts +2 -2
  38. package/dist/types/helpers/index.d.ts +3 -0
  39. package/dist/types/helpers/number.d.ts +2 -0
  40. package/dist/types/helpers/responses.d.ts +1 -1
  41. package/dist/types/helpers/socket.d.ts +48 -50
  42. package/dist/types/helpers/time.d.ts +0 -11
  43. package/dist/types/helpers/user.d.ts +2 -2
  44. package/dist/types/index.d.ts +0 -1
  45. package/dist/types/types/class.d.ts +6 -6
  46. package/dist/types/types/comments.d.ts +2 -2
  47. package/dist/types/types/contest.d.ts +20 -23
  48. package/dist/types/types/entity.d.ts +13 -19
  49. package/dist/types/types/file.d.ts +6 -0
  50. package/dist/types/types/index.d.ts +3 -1
  51. package/dist/types/types/{company.d.ts → organization.d.ts} +2 -2
  52. package/dist/types/types/prisma.d.ts +2 -2
  53. package/dist/types/types/problems.d.ts +1 -1
  54. package/dist/types/types/scoreboard.d.ts +11 -0
  55. package/dist/types/types/sheet.d.ts +1 -1
  56. package/dist/types/types/socket.d.ts +32 -16
  57. package/dist/types/types/system.d.ts +76 -0
  58. package/dist/types/types/teams.d.ts +8 -8
  59. package/dist/types/types/virtual-user.d.ts +22 -0
  60. package/package.json +1 -1
  61. package/dist/types/constants/company.d.ts +0 -9
  62. package/dist/types/prototypes/Date.d.ts +0 -62
  63. package/dist/types/prototypes/Number.d.ts +0 -7
  64. package/dist/types/prototypes/index.d.ts +0 -3
  65. /package/dist/types/{prototypes/Error.d.ts → helpers/errors.d.ts} +0 -0
@@ -91,20 +91,20 @@ exports.EntityAccess = void 0;
91
91
  EntityAccess["EXPOSED"] = "EXPOSED";
92
92
  })(exports.EntityAccess || (exports.EntityAccess = {}));
93
93
 
94
- exports.CompanyPlan = void 0;
95
- (function (CompanyPlan) {
96
- CompanyPlan["FREE"] = "FREE";
97
- CompanyPlan["STANDARD"] = "STANDARD";
98
- CompanyPlan["PREMIUM"] = "PREMIUM";
99
- CompanyPlan["CUSTOM"] = "CUSTOM";
100
- })(exports.CompanyPlan || (exports.CompanyPlan = {}));
101
- exports.CompanyLogoType = void 0;
102
- (function (CompanyLogoType) {
103
- CompanyLogoType["HORIZONTAL_WHITE"] = "horizontal-white";
104
- CompanyLogoType["HORIZONTAL_COLOR"] = "horizontal-color";
105
- CompanyLogoType["VERTICAL_WHITE"] = "vertical-white";
106
- CompanyLogoType["VERTICAL_COLOR"] = "vertical-color";
107
- })(exports.CompanyLogoType || (exports.CompanyLogoType = {}));
94
+ exports.OrganizationPlan = void 0;
95
+ (function (OrganizationPlan) {
96
+ OrganizationPlan["FREE"] = "FREE";
97
+ OrganizationPlan["STANDARD"] = "STANDARD";
98
+ OrganizationPlan["PREMIUM"] = "PREMIUM";
99
+ OrganizationPlan["CUSTOM"] = "CUSTOM";
100
+ })(exports.OrganizationPlan || (exports.OrganizationPlan = {}));
101
+ exports.OrganizationLogoType = void 0;
102
+ (function (OrganizationLogoType) {
103
+ OrganizationLogoType["HORIZONTAL_WHITE"] = "horizontal-white";
104
+ OrganizationLogoType["HORIZONTAL_COLOR"] = "horizontal-color";
105
+ OrganizationLogoType["VERTICAL_WHITE"] = "vertical-white";
106
+ OrganizationLogoType["VERTICAL_COLOR"] = "vertical-color";
107
+ })(exports.OrganizationLogoType || (exports.OrganizationLogoType = {}));
108
108
 
109
109
  exports.ContestStatus = void 0;
110
110
  (function (ContestStatus) {
@@ -147,7 +147,7 @@ exports.EntityState = void 0;
147
147
  })(exports.EntityState || (exports.EntityState = {}));
148
148
  exports.EntityCollection = void 0;
149
149
  (function (EntityCollection) {
150
- EntityCollection["COMPANY"] = "COMPANY";
150
+ EntityCollection["ORGANIZATION"] = "ORGANIZATION";
151
151
  EntityCollection["PROBLEM"] = "PROBLEM";
152
152
  EntityCollection["CONTEST"] = "CONTEST";
153
153
  EntityCollection["JUDGE"] = "JUDGE";
@@ -156,7 +156,7 @@ exports.EntityCollection = void 0;
156
156
  })(exports.EntityCollection || (exports.EntityCollection = {}));
157
157
  exports.CollectionKey = void 0;
158
158
  (function (CollectionKey) {
159
- CollectionKey["COMPANY"] = "C";
159
+ CollectionKey["ORGANIZATION"] = "C";
160
160
  CollectionKey["USER"] = "U";
161
161
  CollectionKey["PROBLEM"] = "P";
162
162
  CollectionKey["CLASS"] = "K";
@@ -528,7 +528,7 @@ exports.ErrorCode = void 0;
528
528
  ErrorCode["ERR0818"] = "ERR0818";
529
529
  ErrorCode["ERR0819"] = "ERR0819";
530
530
  ErrorCode["ERR0820"] = "ERR0820";
531
- // Company Errors ERR99XXX',
531
+ // Organization Errors ERR99XXX',
532
532
  ErrorCode["ERR9900"] = "ERR9900";
533
533
  ErrorCode["ERR9910"] = "ERR9910";
534
534
  ErrorCode["ERR9911"] = "ERR9911";
@@ -574,14 +574,6 @@ exports.QuizScoringMode = void 0;
574
574
  QuizScoringMode["PARTIAL"] = "PARTIAL";
575
575
  })(exports.QuizScoringMode || (exports.QuizScoringMode = {}));
576
576
 
577
- exports.WebSocketMessageEvent = void 0;
578
- (function (WebSocketMessageEvent) {
579
- WebSocketMessageEvent["PING"] = "PING";
580
- WebSocketMessageEvent["CLIENT_TRACK_LOCATION"] = "CLIENT_TRACK_LOCATION";
581
- WebSocketMessageEvent["CLIENT_TRACK_SCREENSHOT"] = "CLIENT_TRACK_SCREENSHOT";
582
- WebSocketMessageEvent["CLIENT_TRACK_DEVICE"] = "CLIENT_TRACK_DEVICE";
583
- WebSocketMessageEvent["CHAT_COMPLETIONS"] = "CHAT_COMPLETIONS";
584
- })(exports.WebSocketMessageEvent || (exports.WebSocketMessageEvent = {}));
585
577
  /**
586
578
  * Subscriptions of the client. With the TOPIC channels they are not sent to the server anymore:
587
579
  * they only say which channel the client attaches (`getChannelOfWebSocketSubscribeEvent`) and the dispatch key.
@@ -600,17 +592,13 @@ exports.WebSocketSubscriptionEvent = void 0;
600
592
  WebSocketSubscriptionEvent["UNSUBSCRIBE_SUBMISSIONS_CRAWL"] = "UNSUBSCRIBE_SUBMISSIONS_CRAWL";
601
593
  WebSocketSubscriptionEvent["SUBSCRIBE_CONTEST_CHANGES"] = "SUBSCRIBE_CONTEST_CHANGES";
602
594
  WebSocketSubscriptionEvent["UNSUBSCRIBE_CONTEST_CHANGES"] = "UNSUBSCRIBE_CONTEST_CHANGES";
603
- WebSocketSubscriptionEvent["SUBSCRIBE_CLIENT_TRACK"] = "SUBSCRIBE_CLIENT_TRACK";
604
- WebSocketSubscriptionEvent["UNSUBSCRIBE_CLIENT_TRACK"] = "UNSUBSCRIBE_CLIENT_TRACK";
605
595
  WebSocketSubscriptionEvent["SUBSCRIBE_USER_NOTIFICATION"] = "SUBSCRIBE_USER_NOTIFICATION";
606
596
  WebSocketSubscriptionEvent["UNSUBSCRIBE_USER_NOTIFICATION"] = "UNSUBSCRIBE_USER_NOTIFICATION";
607
- // an administrator watching the data (screenshots, location, device) sent by another client
608
- WebSocketSubscriptionEvent["SUBSCRIBE_CLIENT_TRACK_DATA"] = "SUBSCRIBE_CLIENT_TRACK_DATA";
609
- WebSocketSubscriptionEvent["UNSUBSCRIBE_CLIENT_TRACK_DATA"] = "UNSUBSCRIBE_CLIENT_TRACK_DATA";
597
+ WebSocketSubscriptionEvent["SUBSCRIBE_SUBMISSIONS_JUDGING"] = "SUBSCRIBE_SUBMISSIONS_JUDGING";
598
+ WebSocketSubscriptionEvent["UNSUBSCRIBE_SUBMISSIONS_JUDGING"] = "UNSUBSCRIBE_SUBMISSIONS_JUDGING";
610
599
  })(exports.WebSocketSubscriptionEvent || (exports.WebSocketSubscriptionEvent = {}));
611
600
  exports.WebSocketResponseEvent = void 0;
612
601
  (function (WebSocketResponseEvent) {
613
- WebSocketResponseEvent["PONG"] = "PONG";
614
602
  WebSocketResponseEvent["CODE_RUN_STATUS"] = "CODE_RUN_STATUS";
615
603
  WebSocketResponseEvent["SUBMISSION_RUN_STATUS"] = "SUBMISSION_RUN_STATUS";
616
604
  WebSocketResponseEvent["USER_MESSAGE"] = "USER_MESSAGE";
@@ -620,15 +608,13 @@ exports.WebSocketResponseEvent = void 0;
620
608
  WebSocketResponseEvent["SEND_DATA_EC2_INSTANCES_LIST"] = "SEND_DATA_EC2_INSTANCES_LIST";
621
609
  WebSocketResponseEvent["SEND_DATA_SSM_SESSIONS_LIST"] = "SEND_DATA_SSM_SESSIONS_LIST";
622
610
  WebSocketResponseEvent["SEND_DATA_RUN_COMMAND"] = "SEND_DATA_RUN_COMMAND";
623
- WebSocketResponseEvent["SEND_DATA_CLIENT_TRACK"] = "SEND_DATA_CLIENT_TRACK";
624
- WebSocketResponseEvent["SEND_DATA_CHAT_COMPLETIONS"] = "SEND_DATA_CHAT_COMPLETIONS";
625
611
  WebSocketResponseEvent["PROBLEM_CRAWLED"] = "PROBLEM_CRAWLED";
626
612
  WebSocketResponseEvent["SUBMISSIONS_CRAWL"] = "SUBMISSIONS_CRAWL";
627
613
  WebSocketResponseEvent["CONTEST_CHANGES"] = "CONTEST_CHANGES";
628
- WebSocketResponseEvent["CLIENT_TRACK"] = "CLIENT_TRACK";
629
614
  WebSocketResponseEvent["USER_NOTIFICATION_"] = "USER_NOTIFICATION_";
630
615
  WebSocketResponseEvent["USER_NOTIFICATION_SUBMISSION"] = "USER_NOTIFICATION_SUBMISSION";
631
616
  WebSocketResponseEvent["USER_NOTIFICATION_CONTEST_CLARIFICATION"] = "USER_NOTIFICATION_CONTEST_CLARIFICATION";
617
+ WebSocketResponseEvent["SUBMISSION_JUDGING"] = "SUBMISSION_JUDGING";
632
618
  })(exports.WebSocketResponseEvent || (exports.WebSocketResponseEvent = {}));
633
619
  /**
634
620
  * Roles of a contest, with the same names as the contest members in the DB.
@@ -644,6 +630,25 @@ exports.ContestChannelRole = void 0;
644
630
  ContestChannelRole["GUESTS"] = "guests";
645
631
  ContestChannelRole["SPECTATORS"] = "spectators";
646
632
  })(exports.ContestChannelRole || (exports.ContestChannelRole = {}));
633
+ /**
634
+ * Roles of a problem, the ones computed by `getProblemAccessPermissions` (backend).
635
+ * Each role has its own Ably channel: `problem:{problemKey}:{role}` (see `CHANNEL_PROBLEM`).
636
+ */
637
+ exports.ProblemChannelRole = void 0;
638
+ (function (ProblemChannelRole) {
639
+ ProblemChannelRole["ADMINISTRATORS"] = "administrators";
640
+ ProblemChannelRole["MANAGERS"] = "managers";
641
+ ProblemChannelRole["SPECTATORS"] = "spectators";
642
+ })(exports.ProblemChannelRole || (exports.ProblemChannelRole = {}));
643
+ /**
644
+ * Roles of the public channels of a user: `user:{userId}:{role}` (see `CHANNEL_USER_ROLE`).
645
+ * There are no per-user permissions: `spectators` is everyone who can list the submissions of the user.
646
+ * The private channel of the user is `user:{userId}` (see `CHANNEL_USER`).
647
+ */
648
+ exports.UserChannelRole = void 0;
649
+ (function (UserChannelRole) {
650
+ UserChannelRole["SPECTATORS"] = "spectators";
651
+ })(exports.UserChannelRole || (exports.UserChannelRole = {}));
647
652
 
648
653
  exports.DataViewMode = void 0;
649
654
  (function (DataViewMode) {
@@ -1337,25 +1342,25 @@ const HEADER_JUKI_SECRET_TOKEN = 'x-juki-secret-token';
1337
1342
  const HEADER_JUKI_INTERNAL_API_KEY = 'x-juki-internal-api-key';
1338
1343
  const COOKIE_JUKI_SESSION_ID = 'juki-session-id';
1339
1344
 
1340
- const JUKI_APP_COMPANY_KEY = 'juki-app';
1341
- const COMPANY_PLAN = {
1342
- [exports.CompanyPlan.FREE]: {
1343
- value: exports.CompanyPlan.FREE,
1345
+ const JUKI_APP_ORGANIZATION_KEY = 'juki-app';
1346
+ const ORGANIZATION_PLAN = {
1347
+ [exports.OrganizationPlan.FREE]: {
1348
+ value: exports.OrganizationPlan.FREE,
1344
1349
  label: 'free',
1345
1350
  description: 'the resources, runners and compilers, are shared with the juki.app giving priority to juki.app',
1346
1351
  },
1347
- [exports.CompanyPlan.STANDARD]: {
1348
- value: exports.CompanyPlan.STANDARD,
1352
+ [exports.OrganizationPlan.STANDARD]: {
1353
+ value: exports.OrganizationPlan.STANDARD,
1349
1354
  label: 'standard',
1350
1355
  description: 'the resources are dedicated, 1 runner and 1 compiler',
1351
1356
  },
1352
- [exports.CompanyPlan.PREMIUM]: {
1353
- value: exports.CompanyPlan.PREMIUM,
1357
+ [exports.OrganizationPlan.PREMIUM]: {
1358
+ value: exports.OrganizationPlan.PREMIUM,
1354
1359
  label: 'premium',
1355
1360
  description: 'the resources are dedicated and on demand use with at least 1 runner and 1 compiler',
1356
1361
  },
1357
- [exports.CompanyPlan.CUSTOM]: {
1358
- value: exports.CompanyPlan.CUSTOM,
1362
+ [exports.OrganizationPlan.CUSTOM]: {
1363
+ value: exports.OrganizationPlan.CUSTOM,
1359
1364
  label: 'custom',
1360
1365
  description: 'the resources are dedicated and on demand use with at least 1 (settable) runner and 1 (settable) compiler',
1361
1366
  },
@@ -1978,18 +1983,18 @@ const ERROR = {
1978
1983
  [exports.ErrorCode.ERR9997]: { value: exports.ErrorCode.ERR9997, message: 'aborted request', status: 400 },
1979
1984
  [exports.ErrorCode.ERR9998]: { value: exports.ErrorCode.ERR9998, message: 'error on response', status: 400 },
1980
1985
  [exports.ErrorCode.ERR9999]: { value: exports.ErrorCode.ERR9999, message: 'service no found', status: 400 },
1981
- // COMPANY ERRORS ERR99XX
1982
- [exports.ErrorCode.ERR9900]: { value: exports.ErrorCode.ERR9900, message: 'internal server error on company service', status: 500 },
1983
- // Company server errors
1984
- [exports.ErrorCode.ERR9910]: { value: exports.ErrorCode.ERR9910, message: 'company not created', status: 500 },
1985
- [exports.ErrorCode.ERR9911]: { value: exports.ErrorCode.ERR9911, message: 'company not found', status: 500 },
1986
- [exports.ErrorCode.ERR9912]: { value: exports.ErrorCode.ERR9912, message: 'company not updated', status: 500 },
1987
- [exports.ErrorCode.ERR9913]: { value: exports.ErrorCode.ERR9913, message: 'company not deleted', status: 500 },
1988
- // Company user permission error
1989
- [exports.ErrorCode.ERR9914]: { value: exports.ErrorCode.ERR9914, message: 'not allowed to create the company', status: 400 },
1990
- [exports.ErrorCode.ERR9915]: { value: exports.ErrorCode.ERR9915, message: 'not allowed to view the company', status: 400 },
1991
- [exports.ErrorCode.ERR9916]: { value: exports.ErrorCode.ERR9916, message: 'not allowed to updated the company', status: 400 },
1992
- [exports.ErrorCode.ERR9917]: { value: exports.ErrorCode.ERR9917, message: 'not allowed to deleted the company', status: 400 },
1986
+ // ORGANIZATION ERRORS ERR99XX
1987
+ [exports.ErrorCode.ERR9900]: { value: exports.ErrorCode.ERR9900, message: 'internal server error on organization service', status: 500 },
1988
+ // Organization server errors
1989
+ [exports.ErrorCode.ERR9910]: { value: exports.ErrorCode.ERR9910, message: 'organization not created', status: 500 },
1990
+ [exports.ErrorCode.ERR9911]: { value: exports.ErrorCode.ERR9911, message: 'organization not found', status: 500 },
1991
+ [exports.ErrorCode.ERR9912]: { value: exports.ErrorCode.ERR9912, message: 'organization not updated', status: 500 },
1992
+ [exports.ErrorCode.ERR9913]: { value: exports.ErrorCode.ERR9913, message: 'organization not deleted', status: 500 },
1993
+ // Organization user permission error
1994
+ [exports.ErrorCode.ERR9914]: { value: exports.ErrorCode.ERR9914, message: 'not allowed to create the organization', status: 400 },
1995
+ [exports.ErrorCode.ERR9915]: { value: exports.ErrorCode.ERR9915, message: 'not allowed to view the organization', status: 400 },
1996
+ [exports.ErrorCode.ERR9916]: { value: exports.ErrorCode.ERR9916, message: 'not allowed to updated the organization', status: 400 },
1997
+ [exports.ErrorCode.ERR9917]: { value: exports.ErrorCode.ERR9917, message: 'not allowed to deleted the organization', status: 400 },
1993
1998
  // USER ERRORS ERR00XX
1994
1999
  [exports.ErrorCode.ERR0000]: { value: exports.ErrorCode.ERR0000, message: 'internal server error on users service', status: 500 },
1995
2000
  // User server errors
@@ -2235,7 +2240,7 @@ const EMPTY_USER_PERMISSIONS = {
2235
2240
  create: false,
2236
2241
  manage: false,
2237
2242
  },
2238
- company: {
2243
+ organization: {
2239
2244
  manage: false,
2240
2245
  administrate: false,
2241
2246
  },
@@ -2244,46 +2249,37 @@ const EMPTY_USER_PERMISSIONS = {
2244
2249
  },
2245
2250
  };
2246
2251
 
2247
- // LEGACY channels (fan-out per client through the subscriptions registry in Redis)
2248
- /** @deprecated the subscriptions registry was replaced by the TOPIC channels granted in the Ably token */
2249
- const CHANNEL_PUBLISH_SUBSCRIPTIONS = 'pub:subscriptions';
2250
- /** @deprecated not used, the events arrive by the TOPIC channels */
2251
- const CHANNEL_SUBSCRIBE_NOTIFICATIONS = 'sub:notifications';
2252
- /** @deprecated the events arrive by the TOPIC channels */
2253
- const CHANNEL_SUBSCRIBE_CLIENT = (clientId) => `sub:client:${clientId}`;
2254
- /** messages from the clients to the backend (chat completions, client track screenshots) */
2255
- const CHANNEL_PUBLISH_MESSAGES = 'pub:messages';
2256
- /** @deprecated global presence channel (limited to 200 members by Ably), replaced by CHANNEL_COMPANY_PRESENCE */
2257
- const CHANNEL_PRESENCE_CLIENT = 'pre:client';
2258
2252
  // TOPIC channels
2259
2253
  // The backend publishes each event once on the channel of its topic and Ably does the fan-out.
2260
2254
  // Who can subscribe to each channel is decided by the API in the Ably token (capability), never by the client.
2261
2255
  // Dynamic segments are encoded so a key can never inject a `:` (the Ably segment separator used by the wildcards).
2262
2256
  const segment = (value) => encodeURIComponent(value);
2263
- /** private: events of one session (code runs, requested data, client track commands) */
2257
+ /** private: events of one session (code runs, requested data) */
2264
2258
  const CHANNEL_SESSION = (sessionId) => `session:${segment(sessionId)}`;
2265
- /** private: events of one user (own submissions while the contest is frozen, notifications) */
2259
+ /** private: events of one user (own submissions while the contest is frozen, notifications, own problem crawls) */
2266
2260
  const CHANNEL_USER = (userId) => `user:${segment(userId)}`;
2261
+ /** per role: public events of one user (judging of its submissions visible to everyone, see `UserChannelRole`) */
2262
+ const CHANNEL_USER_ROLE = (userId, role) => `user:${segment(userId)}:${role}`;
2267
2263
  /** public: status of a submission when it is visible to everyone */
2268
2264
  const CHANNEL_SUBMISSION = (submitId) => `submission:${segment(submitId)}`;
2269
- /** public: changes of a problem */
2270
- const CHANNEL_PROBLEM = (problemKey) => `problem:${segment(problemKey)}`;
2265
+ /** per role: events of a problem for one role (judging of its submissions, see `ProblemChannelRole`) */
2266
+ const CHANNEL_PROBLEM = (problemKey, role) => `problem:${segment(problemKey)}:${role}`;
2271
2267
  /** per role: events of a contest for one role (and the roles above it, see `ContestChannelRole`) */
2272
2268
  const CHANNEL_CONTEST = (contestKey, role) => `contest:${segment(contestKey)}:${role}`;
2273
- /** system administrators only: data sent by a tracked client (screenshots, location, device) */
2274
- const CHANNEL_CLIENT_TRACK = (trackedClientId) => `client-track:${segment(trackedClientId)}`;
2275
2269
  /**
2276
- * presence of the clients (tabs) of the logged users of a company (by its key), data: `UserPresenceData`.
2277
- * The clients only enter (capability `presence`), only the administrators of the company receive it
2270
+ * presence of the clients (tabs) of the logged users of a organization (by its key), data: `UserPresenceData`.
2271
+ * The clients only enter (capability `presence`), only the administrators of the organization receive it
2278
2272
  * (capability `presence-subscribe`). Ably limits the presence members per channel (200 by default,
2279
2273
  * more with server-side batching enabled on the `presence` namespace).
2280
2274
  * The identity of a member is its `clientId` (`sessionId|uiId`, verified by Ably), never its data.
2281
2275
  */
2282
- const CHANNEL_COMPANY_PRESENCE = (companyKey) => `presence:company:${segment(companyKey)}`;
2283
- // capability resources (wildcards) of the public channels
2276
+ const CHANNEL_ORGANIZATION_PRESENCE = (organizationKey) => `presence:organization:${segment(organizationKey)}`;
2277
+ // capability resources (wildcards) of the public channels.
2278
+ // Ably: a trailing `*` replaces one or more segments, any other `*` exactly one segment. So `user:*:spectators`
2279
+ // matches every `user:{userId}:spectators` but never the private `user:{userId}`.
2280
+ // There is no public `problem:*`: it would also match the role channels `problem:{problemKey}:{role}`.
2284
2281
  const CHANNEL_SUBMISSION_ALL = 'submission:*';
2285
- const CHANNEL_PROBLEM_ALL = 'problem:*';
2286
- const CHANNEL_CLIENT_TRACK_ALL = 'client-track:*';
2282
+ const CHANNEL_USER_SPECTATORS_ALL = `user:*:${exports.UserChannelRole.SPECTATORS}`;
2287
2283
  /**
2288
2284
  * Returns the contest and role of a `CHANNEL_CONTEST` channel name, or null if it is not one.
2289
2285
  */
@@ -2294,6 +2290,16 @@ const getContestChannelParams = (channel) => {
2294
2290
  }
2295
2291
  return { contestKey: decodeURIComponent(contestKey), role: role };
2296
2292
  };
2293
+ /**
2294
+ * Returns the problem and role of a `CHANNEL_PROBLEM` channel name, or null if it is not one.
2295
+ */
2296
+ const getProblemChannelParams = (channel) => {
2297
+ const [namespace, problemKey, role, ...rest] = channel.split(':');
2298
+ if (namespace !== 'problem' || !problemKey || rest.length || !Object.values(exports.ProblemChannelRole).includes(role)) {
2299
+ return null;
2300
+ }
2301
+ return { problemKey: decodeURIComponent(problemKey), role: role };
2302
+ };
2297
2303
 
2298
2304
  const NEW_PAGE_SHEET = () => ({
2299
2305
  id: uuid.v4(),
@@ -2385,31 +2391,212 @@ const isContestAssignment = (assignment) => {
2385
2391
  };
2386
2392
 
2387
2393
  const getAssignmentCommentKey = (classKey, cycleKey, sessionKey, assignmentKey) => `class:${classKey}|cycle:${cycleKey}|session:${sessionKey}|assignment:${assignmentKey}`;
2388
- const getAssignmentUserCommentKey = (classKey, cycleKey, sessionKey, assignmentKey, userNickname, userCompany) => `class:${classKey}|cycle:${cycleKey}|session:${sessionKey}|assignment:${assignmentKey}|user_nickname:${userNickname}|user_company:${userCompany}`;
2394
+ const getAssignmentUserCommentKey = (classKey, cycleKey, sessionKey, assignmentKey, userNickname, userOrganization) => `class:${classKey}|cycle:${cycleKey}|session:${sessionKey}|assignment:${assignmentKey}|user_nickname:${userNickname}|user_organization:${userOrganization}`;
2389
2395
  const getProblemCommentKey = (problemKey) => `problem:${problemKey}`;
2390
2396
  const getContestCommentKey = (contestKey) => `contest:${contestKey}`;
2391
2397
 
2392
2398
  const isEndlessContest = (settings) => {
2393
- return settings?.startTimestamp === MIN_DATE.getTime()
2394
- && settings?.frozenTimestamp === MAX_DATE.getTime()
2395
- && settings?.quietTimestamp === MAX_DATE.getTime()
2396
- && settings?.endTimestamp === MAX_DATE.getTime()
2399
+ return settings?.startsAt === MIN_DATE.getTime()
2400
+ && settings?.frozenAt === MAX_DATE.getTime()
2401
+ && settings?.silencedAt === MAX_DATE.getTime()
2402
+ && settings?.endsAt === MAX_DATE.getTime()
2397
2403
  && settings?.penalty === 0;
2398
2404
  };
2399
2405
  const isGlobalContest = (settings) => {
2400
- return settings?.startTimestamp === 0
2401
- && settings?.frozenTimestamp === 0
2402
- && settings?.quietTimestamp === 0
2403
- && settings?.endTimestamp === 0
2406
+ return settings?.startsAt === 0
2407
+ && settings?.frozenAt === 0
2408
+ && settings?.silencedAt === 0
2409
+ && settings?.endsAt === 0
2404
2410
  && settings?.penalty === 0;
2405
2411
  };
2406
2412
  const isPastContest = (settings) => {
2407
- return Date.now() > (settings?.endTimestamp ?? 0);
2413
+ return Date.now() > (settings?.endsAt ?? 0);
2408
2414
  };
2409
2415
  const isFutureContest = (settings) => {
2410
- return (settings?.startTimestamp ?? 0) > Date.now();
2416
+ return (settings?.startsAt ?? 0) > Date.now();
2411
2417
  };
2412
2418
 
2419
+ const changeYear = (date, year) => {
2420
+ const newDate = new Date(date);
2421
+ newDate.setFullYear(year);
2422
+ return newDate;
2423
+ };
2424
+ const changeMonth = (date, monthIndex) => {
2425
+ const newDate = new Date(date);
2426
+ newDate.setMonth(monthIndex);
2427
+ return newDate;
2428
+ };
2429
+ const changeDay = (date, day) => {
2430
+ const newDate = new Date(date);
2431
+ newDate.setDate(day);
2432
+ return newDate;
2433
+ };
2434
+ const changeHours = (date, hours) => {
2435
+ const newDate = new Date(date);
2436
+ newDate.setHours(hours);
2437
+ return newDate;
2438
+ };
2439
+ const changeMinutes = (date, minutes) => {
2440
+ const newDate = new Date(date);
2441
+ newDate.setMinutes(minutes);
2442
+ return newDate;
2443
+ };
2444
+ const changeSeconds = (date, seconds) => {
2445
+ const newDate = new Date(date);
2446
+ newDate.setSeconds(seconds);
2447
+ return newDate;
2448
+ };
2449
+ const changeMilliseconds = (date, milliseconds) => {
2450
+ const newDate = new Date(date);
2451
+ newDate.setMilliseconds(milliseconds);
2452
+ return newDate;
2453
+ };
2454
+ const decreaseYear = (date, count = 1) => changeYear(date, date.getFullYear() - count);
2455
+ const increaseYear = (date, count = 1) => changeYear(date, date.getFullYear() + count);
2456
+ const decreaseMonth = (date) => {
2457
+ const newDate = new Date(date);
2458
+ newDate.setMonth(newDate.getMonth() - 1);
2459
+ return newDate;
2460
+ };
2461
+ const increaseMonth = (date) => {
2462
+ const newDate = new Date(date);
2463
+ newDate.setMonth(newDate.getMonth() + 1);
2464
+ return newDate;
2465
+ };
2466
+ const decreaseDay = (date) => {
2467
+ const newDate = new Date(date);
2468
+ newDate.setDate(newDate.getDate() - 1);
2469
+ return newDate;
2470
+ };
2471
+ const increaseDay = (date) => {
2472
+ const newDate = new Date(date);
2473
+ newDate.setDate(newDate.getDate() + 1);
2474
+ return newDate;
2475
+ };
2476
+ const startOfDay = (date) => {
2477
+ const newDate = new Date(date);
2478
+ newDate.setHours(0, 0, 0, 0);
2479
+ return newDate;
2480
+ };
2481
+ const endOfDay = (date) => {
2482
+ const newDate = new Date(date);
2483
+ newDate.setHours(23, 59, 59, 999);
2484
+ return newDate;
2485
+ };
2486
+ const startOfMonth = (date) => {
2487
+ const newDate = new Date(date);
2488
+ newDate.setDate(1);
2489
+ return startOfDay(newDate);
2490
+ };
2491
+ const endOfMonth = (date) => {
2492
+ const nextMonth = startOfMonth(increaseMonth(date));
2493
+ return new Date(nextMonth.getTime() - 1);
2494
+ };
2495
+ const startOfYear = (date) => {
2496
+ const newDate = new Date(date);
2497
+ newDate.setMonth(0);
2498
+ return startOfMonth(newDate);
2499
+ };
2500
+ const endOfYear = (date) => {
2501
+ const nextYear = startOfYear(increaseYear(date));
2502
+ return new Date(nextYear.getTime() - 1);
2503
+ };
2504
+ const startOfWeek = (date) => {
2505
+ const newDate = new Date(date);
2506
+ while (newDate.getDay()) {
2507
+ newDate.setDate(newDate.getDate() - 1);
2508
+ }
2509
+ return startOfDay(newDate);
2510
+ };
2511
+ const endOfWeek = (date) => {
2512
+ const newDate = new Date(date);
2513
+ while (newDate.getDay() < 6) {
2514
+ newDate.setDate(newDate.getDate() + 1);
2515
+ }
2516
+ return endOfDay(newDate);
2517
+ };
2518
+ const startOfHour = (date) => {
2519
+ const newDate = new Date(date);
2520
+ newDate.setMinutes(0, 0, 0);
2521
+ return newDate;
2522
+ };
2523
+ const endOfHour = (date) => {
2524
+ const newDate = new Date(date);
2525
+ newDate.setMinutes(59, 59, 999);
2526
+ return newDate;
2527
+ };
2528
+ const startOfMinute = (date) => {
2529
+ const newDate = new Date(date);
2530
+ newDate.setSeconds(0, 0);
2531
+ return newDate;
2532
+ };
2533
+ const endOfMinute = (date) => {
2534
+ const newDate = new Date(date);
2535
+ newDate.setSeconds(59, 999);
2536
+ return newDate;
2537
+ };
2538
+ const startOfSecond = (date) => {
2539
+ const newDate = new Date(date);
2540
+ newDate.setMilliseconds(0);
2541
+ return newDate;
2542
+ };
2543
+ const endOfSecond = (date) => {
2544
+ const newDate = new Date(date);
2545
+ newDate.setMilliseconds(999);
2546
+ return newDate;
2547
+ };
2548
+ const isEqual = (a, b) => a.getTime() === b.getTime();
2549
+ const isSameYear = (a, b) => a.getFullYear() === b.getFullYear();
2550
+ const isSameMonth = (a, b) => isSameYear(a, b) && a.getMonth() === b.getMonth();
2551
+ const isSameDay = (a, b) => isSameMonth(a, b) && a.getDate() === b.getDate();
2552
+ const isSameHour = (a, b) => isSameDay(a, b) && a.getHours() === b.getHours();
2553
+ const isSameMinute = (a, b) => isSameHour(a, b) && a.getMinutes() === b.getMinutes();
2554
+ const isSameSecond = (a, b) => isSameMinute(a, b) && a.getSeconds() === b.getSeconds();
2555
+ const isSameMillisecond = (a, b) => isEqual(a, b);
2556
+ const isToday = (date) => isSameDay(date, new Date());
2557
+ const isValidDate = (date) => date instanceof Date && !Number.isNaN(date.getTime());
2558
+ const isAfter = (a, b) => a.getTime() > b.getTime();
2559
+ const isBefore = (a, b) => a.getTime() < b.getTime();
2560
+ const isYearAfter = (a, b) => a.getFullYear() > b.getFullYear();
2561
+ const isMonthAfter = (a, b) => isYearAfter(a, b) || (isSameYear(a, b) && a.getMonth() > b.getMonth());
2562
+ const isDayAfter = (a, b) => isMonthAfter(a, b) || (isSameMonth(a, b) && a.getDate() > b.getDate());
2563
+ const isHoursAfter = (a, b) => isDayAfter(a, b) || (isSameDay(a, b) && a.getHours() > b.getHours());
2564
+ const isMinutesAfter = (a, b) => isHoursAfter(a, b) || (isSameHour(a, b) && a.getMinutes() > b.getMinutes());
2565
+ const isSecondsAfter = (a, b) => isMinutesAfter(a, b) || (isSameMinute(a, b) && a.getSeconds() > b.getSeconds());
2566
+ const isMillisecondsAfter = (a, b) => isSecondsAfter(a, b) || (isSameSecond(a, b) && a.getMilliseconds() > b.getMilliseconds());
2567
+ const isYearBefore = (a, b) => a.getFullYear() < b.getFullYear();
2568
+ const isMonthBefore = (a, b) => isYearBefore(a, b) || (isSameYear(a, b) && a.getMonth() < b.getMonth());
2569
+ const isDayBefore = (a, b) => isMonthBefore(a, b) || (isSameMonth(a, b) && a.getDate() < b.getDate());
2570
+ const isHoursBefore = (a, b) => isDayBefore(a, b) || (isSameDay(a, b) && a.getHours() < b.getHours());
2571
+ const isMinutesBefore = (a, b) => isHoursBefore(a, b) || (isSameHour(a, b) && a.getMinutes() < b.getMinutes());
2572
+ const isSecondsBefore = (a, b) => isMinutesBefore(a, b) || (isSameMinute(a, b) && a.getSeconds() < b.getSeconds());
2573
+ const isMillisecondsBefore = (a, b) => isSecondsBefore(a, b) || (isSameSecond(a, b) && a.getMilliseconds() < b.getMilliseconds());
2574
+ const isWithinInterval = (date, { start, end }, cmp = '[]') => (cmp.charAt(0) === '[' ? isEqual(date, start) || isAfter(date, start) : isAfter(date, start)) &&
2575
+ (cmp.charAt(1) === ']' ? isEqual(date, end) || isBefore(date, end) : isBefore(date, end));
2576
+ const normalizeToLocalStartOfDay = (timestamp) => {
2577
+ const d = new Date(timestamp);
2578
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate());
2579
+ };
2580
+ const normalizeToLocalStartOfHour = (timestamp) => {
2581
+ const d = new Date(timestamp);
2582
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours());
2583
+ };
2584
+ const normalizeToLocalStartOfMinutes = (timestamp) => {
2585
+ const d = new Date(timestamp);
2586
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes());
2587
+ };
2588
+ const normalizeToLocalStartOfSeconds = (timestamp) => {
2589
+ const d = new Date(timestamp);
2590
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds());
2591
+ };
2592
+ const getYears = (d) => d.getFullYear();
2593
+ const getMonths = (d) => d.getFullYear() * 12 + d.getMonth();
2594
+ const getDays = (d) => Math.floor(normalizeToLocalStartOfDay(d).getTime() / ONE_DAY);
2595
+ const getHours = (d) => Math.floor(normalizeToLocalStartOfHour(d).getTime() / ONE_HOUR);
2596
+ const getMinutes = (d) => Math.floor(normalizeToLocalStartOfMinutes(d).getTime() / ONE_MINUTE);
2597
+ const getSeconds = (d) => Math.floor(normalizeToLocalStartOfSeconds(d).getTime() / 1000);
2598
+ const getMilliseconds = (d) => d.getTime();
2599
+
2413
2600
  const getDocumentAccess = (document) => {
2414
2601
  switch (true) {
2415
2602
  case (document?.members?.rankAdministrators === exports.EntityMembersRank.NONE || document?.members?.rankAdministrators === exports.EntityMembersRank.CLOSE)
@@ -2446,7 +2633,7 @@ const isUserMember = (member) => {
2446
2633
  const isTeamMember = (member) => {
2447
2634
  return typeof member.teamId === 'string';
2448
2635
  };
2449
- const toEntityMembersDTO = (members) => {
2636
+ const toEntityMembersDto = (members) => {
2450
2637
  return {
2451
2638
  rankAdministrators: members.rankAdministrators,
2452
2639
  administrators: Object.keys(members.administrators),
@@ -2461,6 +2648,21 @@ const toEntityMembersDTO = (members) => {
2461
2648
  };
2462
2649
  };
2463
2650
 
2651
+ class JkError extends Error {
2652
+ constructor(code, custom) {
2653
+ const message = custom?.message || ERROR[code].message;
2654
+ super(message);
2655
+ this.message = message;
2656
+ this.code = code;
2657
+ if (custom?.stack) {
2658
+ this.stack = custom.stack;
2659
+ }
2660
+ if (custom?.data) {
2661
+ this.data = custom.data;
2662
+ }
2663
+ }
2664
+ }
2665
+
2464
2666
  function removeExtension(fileName) {
2465
2667
  const i = fileName.lastIndexOf('.');
2466
2668
  return i !== -1 ? fileName.substring(0, i) : fileName;
@@ -2615,6 +2817,9 @@ const getDataLog = (log) => {
2615
2817
  };
2616
2818
  };
2617
2819
 
2820
+ const padStart = (n, maxLength, fillString = '0') => `${n}`.padStart(maxLength, fillString);
2821
+ const padEnd = (n, maxLength, fillString = '0') => `${n}`.padEnd(maxLength, fillString);
2822
+
2618
2823
  function memorySizeOf(obj) {
2619
2824
  let bytes = 0;
2620
2825
  function sizeOf(obj) {
@@ -2649,247 +2854,6 @@ function memorySizeOf(obj) {
2649
2854
  return sizeOf(obj);
2650
2855
  }
2651
2856
 
2652
- /* eslint-disable no-extend-native */
2653
- Date.prototype.changeYear = function (year) {
2654
- const newDate = new Date(this);
2655
- newDate.setFullYear(year);
2656
- return newDate;
2657
- };
2658
- Date.prototype.changeMonth = function (monthIndex) {
2659
- const newDate = new Date(this);
2660
- newDate.setMonth(monthIndex);
2661
- return newDate;
2662
- };
2663
- Date.prototype.changeDay = function (date) {
2664
- const newDate = new Date(this);
2665
- newDate.setDate(date);
2666
- return newDate;
2667
- };
2668
- Date.prototype.changeHours = function (hours) {
2669
- const newDate = new Date(this);
2670
- newDate.setHours(hours);
2671
- return newDate;
2672
- };
2673
- Date.prototype.changeMinutes = function (minutes) {
2674
- const newDate = new Date(this);
2675
- newDate.setMinutes(minutes);
2676
- return newDate;
2677
- };
2678
- Date.prototype.changeSeconds = function (seconds) {
2679
- const newDate = new Date(this);
2680
- newDate.setSeconds(seconds);
2681
- return newDate;
2682
- };
2683
- Date.prototype.changeMilliseconds = function (milliseconds) {
2684
- const newDate = new Date(this);
2685
- newDate.setMilliseconds(milliseconds);
2686
- return newDate;
2687
- };
2688
- Date.prototype.decreaseYear = function (count = 1) {
2689
- return this.changeYear(this.getFullYear() - count);
2690
- };
2691
- Date.prototype.increaseYear = function (count = 1) {
2692
- return this.changeYear(this.getFullYear() + count);
2693
- };
2694
- Date.prototype.decreaseMonth = function () {
2695
- const newDate = new Date(this);
2696
- newDate.setMonth(newDate.getMonth() - 1);
2697
- return newDate;
2698
- };
2699
- Date.prototype.increaseMonth = function () {
2700
- const newDate = new Date(this);
2701
- newDate.setMonth(newDate.getMonth() + 1);
2702
- return newDate;
2703
- };
2704
- Date.prototype.increaseDay = function () {
2705
- const newDate = new Date(this);
2706
- newDate.setDate(newDate.getDate() + 1);
2707
- return newDate;
2708
- };
2709
- Date.prototype.decreaseDay = function () {
2710
- const newDate = new Date(this);
2711
- newDate.setDate(newDate.getDate() - 1);
2712
- return newDate;
2713
- };
2714
- Date.prototype.startOfYear = function () {
2715
- const newDate = new Date(this);
2716
- newDate.setMonth(0);
2717
- return newDate.startOfMonth();
2718
- };
2719
- Date.prototype.endOfYear = function () {
2720
- const nextMonth = this.increaseYear().startOfYear();
2721
- return new Date(nextMonth.getTime() - 1);
2722
- };
2723
- Date.prototype.startOfMonth = function () {
2724
- const newDate = new Date(this);
2725
- newDate.setDate(1);
2726
- return newDate.startOfDay();
2727
- };
2728
- Date.prototype.endOfMonth = function () {
2729
- const nextMonth = this.increaseMonth().startOfMonth();
2730
- return new Date(nextMonth.getTime() - 1);
2731
- };
2732
- Date.prototype.startOfWeek = function () {
2733
- const newDate = new Date(this);
2734
- while (newDate.getDay()) {
2735
- newDate.setDate(newDate.getDate() - 1);
2736
- }
2737
- return newDate.startOfDay();
2738
- };
2739
- Date.prototype.endOfWeek = function () {
2740
- const newDate = new Date(this);
2741
- while (newDate.getDay() < 6) {
2742
- newDate.setDate(newDate.getDate() - 1);
2743
- }
2744
- return newDate.endOfDay();
2745
- };
2746
- Date.prototype.startOfDay = function () {
2747
- const newDate = new Date(this);
2748
- newDate.setHours(0, 0, 0, 0);
2749
- return newDate;
2750
- };
2751
- Date.prototype.endOfDay = function () {
2752
- const newDate = new Date(this);
2753
- newDate.setHours(23, 59, 59, 999);
2754
- return newDate;
2755
- };
2756
- Date.prototype.startOfHour = function () {
2757
- const newDate = new Date(this);
2758
- newDate.setMinutes(0, 0, 0);
2759
- return newDate;
2760
- };
2761
- Date.prototype.endOfHour = function () {
2762
- const newDate = new Date(this);
2763
- newDate.setMinutes(59, 59, 999);
2764
- return newDate;
2765
- };
2766
- Date.prototype.startOfMinute = function () {
2767
- const newDate = new Date(this);
2768
- newDate.setSeconds(0, 0);
2769
- return newDate;
2770
- };
2771
- Date.prototype.endOfMinute = function () {
2772
- const newDate = new Date(this);
2773
- newDate.setSeconds(59, 999);
2774
- return newDate;
2775
- };
2776
- Date.prototype.startOfSecond = function () {
2777
- const newDate = new Date(this);
2778
- newDate.setMilliseconds(0);
2779
- return newDate;
2780
- };
2781
- Date.prototype.endOfSecond = function () {
2782
- const newDate = new Date(this);
2783
- newDate.setMilliseconds(999);
2784
- return newDate;
2785
- };
2786
- Date.prototype.isToday = function () {
2787
- const today = new Date();
2788
- return this.isSameDay(today);
2789
- };
2790
- Date.prototype.isEqual = function (date) {
2791
- return this.getTime() === date.getTime();
2792
- };
2793
- Date.prototype.isSameYear = function (date) {
2794
- return this.getFullYear() === date.getFullYear();
2795
- };
2796
- Date.prototype.isSameMonth = function (date) {
2797
- return this.isSameYear(date) && this.getMonth() === date.getMonth();
2798
- };
2799
- Date.prototype.isSameDay = function (date) {
2800
- return this.isSameMonth(date) && this.getDate() === date.getDate();
2801
- };
2802
- Date.prototype.isSameHour = function (date) {
2803
- return this.isSameDay(date) && this.getHours() === date.getHours();
2804
- };
2805
- Date.prototype.isSameMinute = function (date) {
2806
- return this.isSameHour(date) && this.getMinutes() === date.getMinutes();
2807
- };
2808
- Date.prototype.isSameSecond = function (date) {
2809
- return this.isSameMinute(date) && this.getSeconds() === date.getSeconds();
2810
- };
2811
- Date.prototype.isSameMillisecond = function (date) {
2812
- return this.isEqual(date);
2813
- };
2814
- Date.prototype.isValidDate = function () {
2815
- return this instanceof Date && !isNaN(this.getTime());
2816
- };
2817
- Date.prototype.isYearAfter = function (date) {
2818
- return this.getFullYear() > date.getFullYear();
2819
- };
2820
- Date.prototype.isMonthAfter = function (date) {
2821
- return this.isYearAfter(date) || (this.isSameYear(date) && this.getMonth() > date.getMonth());
2822
- };
2823
- Date.prototype.isDayAfter = function (date) {
2824
- return this.isMonthAfter(date) || (this.isSameMonth(date) && this.getDate() > date.getDate());
2825
- };
2826
- Date.prototype.isHoursAfter = function (date) {
2827
- return this.isDayAfter(date) || (this.isSameDay(date) && this.getHours() > date.getHours());
2828
- };
2829
- Date.prototype.isMinutesAfter = function (date) {
2830
- return this.isHoursAfter(date) || (this.isSameHour(date) && this.getMinutes() > date.getMinutes());
2831
- };
2832
- Date.prototype.isSecondsAfter = function (date) {
2833
- return this.isMinutesAfter(date) || (this.isSameMinute(date) && this.getSeconds() > date.getSeconds());
2834
- };
2835
- Date.prototype.isMillisecondsAfter = function (date) {
2836
- return this.isSecondsAfter(date) || (this.isSameSecond(date) && this.getMilliseconds() > date.getMilliseconds());
2837
- };
2838
- Date.prototype.isAfter = function (date) {
2839
- return this.getTime() > date.getTime();
2840
- };
2841
- Date.prototype.isYearBefore = function (date) {
2842
- return this.getFullYear() < date.getFullYear();
2843
- };
2844
- Date.prototype.isMonthBefore = function (date) {
2845
- return this.isYearBefore(date) || (this.isSameYear(date) && this.getMonth() < date.getMonth());
2846
- };
2847
- Date.prototype.isDayBefore = function (date) {
2848
- return this.isMonthBefore(date) || (this.isSameMonth(date) && this.getDate() < date.getDate());
2849
- };
2850
- Date.prototype.isHoursBefore = function (date) {
2851
- return this.isDayBefore(date) || (this.isSameDay(date) && this.getHours() < date.getHours());
2852
- };
2853
- Date.prototype.isMinutesBefore = function (date) {
2854
- return this.isHoursBefore(date) || (this.isSameHour(date) && this.getMinutes() < date.getMinutes());
2855
- };
2856
- Date.prototype.isSecondsBefore = function (date) {
2857
- return this.isMinutesBefore(date) || (this.isSameMinute(date) && this.getSeconds() < date.getSeconds());
2858
- };
2859
- Date.prototype.isMillisecondsBefore = function (date) {
2860
- return this.isSecondsBefore(date) || (this.isSameSecond(date) && this.getMilliseconds() < date.getMilliseconds());
2861
- };
2862
- Date.prototype.isBefore = function (date) {
2863
- return this.getTime() < date.getTime();
2864
- };
2865
- Date.prototype.isWithinInterval = function ({ start, end }, cmp = '[]') {
2866
- return (cmp.charAt(0) === '[' ? this.isEqual(start) || this.isAfter(start) : this.isAfter(start)) &&
2867
- (cmp.charAt(1) === '[' ? this.isEqual(end) || this.isBefore(end) : this.isBefore(end));
2868
- };
2869
-
2870
- class JkError extends Error {
2871
- constructor(code, custom) {
2872
- const message = custom?.message || ERROR[code].message;
2873
- super(message);
2874
- this.message = message;
2875
- this.code = code;
2876
- if (custom?.stack) {
2877
- this.stack = custom.stack;
2878
- }
2879
- if (custom?.data) {
2880
- this.data = custom.data;
2881
- }
2882
- }
2883
- }
2884
-
2885
- /* eslint-disable no-extend-native */
2886
- Number.prototype.padStart = function (maxLength, fillString = '0') {
2887
- return (this + '').padStart(maxLength, fillString);
2888
- };
2889
- Number.prototype.padEnd = function (maxLength, fillString = '0') {
2890
- return (this + '').padEnd(maxLength, fillString);
2891
- };
2892
-
2893
2857
  function toJkError(err) {
2894
2858
  const error = new Error();
2895
2859
  let code = err?.code;
@@ -2983,258 +2947,230 @@ const getDefaultMeta = (contents, sort) => {
2983
2947
  };
2984
2948
 
2985
2949
  const isWebsocketSubscription = (event) => {
2986
- return (Object.values(exports.WebSocketSubscriptionEvent).includes(event?.event) || Object.values(exports.WebSocketMessageEvent).includes(event?.event))
2950
+ return Object.values(exports.WebSocketSubscriptionEvent).includes(event?.event)
2987
2951
  && typeof event?.clientId === 'string' && !!event.clientId;
2988
2952
  };
2989
- // Custom CHANNEL_PUBLISH_MESSAGES
2990
- const isPingWebSocketEventDTO = (event) => {
2991
- return isWebsocketSubscription(event)
2992
- && event?.event === exports.WebSocketMessageEvent.PING;
2993
- };
2994
- const isClientTrackLocationWebSocketEventDTO = (event) => {
2995
- return isWebsocketSubscription(event)
2996
- && event?.event === exports.WebSocketMessageEvent.CLIENT_TRACK_LOCATION;
2997
- };
2998
- const isClientTrackScreenshotWebSocketEventDTO = (event) => {
2999
- return isWebsocketSubscription(event)
3000
- && event?.event === exports.WebSocketMessageEvent.CLIENT_TRACK_SCREENSHOT;
3001
- };
3002
- const isClientTrackDeviceWebSocketEventDTO = (event) => {
3003
- return isWebsocketSubscription(event)
3004
- && event?.event === exports.WebSocketMessageEvent.CLIENT_TRACK_DEVICE;
3005
- };
3006
- const isChatCompletionsWebSocketEventDTO = (event) => {
3007
- return isWebsocketSubscription(event)
3008
- && event?.event === exports.WebSocketMessageEvent.CHAT_COMPLETIONS;
3009
- };
3010
2953
  // CHANNEL_PUBLISH_SUBSCRIPTIONS
3011
- const isSubscribeCodeRunStatusWebSocketEventDTO = (event) => {
2954
+ const isSubscribeCodeRunStatusWebSocketEventDto = (event) => {
3012
2955
  return isWebsocketSubscription(event)
3013
2956
  && event?.event === exports.WebSocketSubscriptionEvent.SUBSCRIBE_CODE_RUN_STATUS
3014
2957
  && typeof event?.runId === 'string' && !!event.runId;
3015
2958
  };
3016
- const isUnsubscribeCodeRunStatusWebSocketEventDTO = (event) => {
2959
+ const isUnsubscribeCodeRunStatusWebSocketEventDto = (event) => {
3017
2960
  return isWebsocketSubscription(event)
3018
2961
  && event?.event === exports.WebSocketSubscriptionEvent.UNSUBSCRIBE_CODE_RUN_STATUS
3019
2962
  && typeof event?.runId === 'string' && !!event.runId;
3020
2963
  };
3021
- const isSubscribeSubmissionRunStatusWebSocketEventDTO = (event) => {
2964
+ const isSubscribeSubmissionRunStatusWebSocketEventDto = (event) => {
3022
2965
  return isWebsocketSubscription(event)
3023
2966
  && event?.event === exports.WebSocketSubscriptionEvent.SUBSCRIBE_SUBMISSION_RUN_STATUS
3024
2967
  && typeof event?.submitId === 'string' && !!event.submitId;
3025
2968
  };
3026
- const isUnsubscribeSubmissionRunStatusWebSocketEventDTO = (event) => {
2969
+ const isUnsubscribeSubmissionRunStatusWebSocketEventDto = (event) => {
3027
2970
  return isWebsocketSubscription(event)
3028
2971
  && event?.event === exports.WebSocketSubscriptionEvent.UNSUBSCRIBE_SUBMISSION_RUN_STATUS
3029
2972
  && typeof event?.submitId === 'string' && !!event.submitId;
3030
2973
  };
3031
- const isSubscribeGetDataWebSocketEventDTO = (event) => {
2974
+ const isSubscribeGetDataWebSocketEventDto = (event) => {
3032
2975
  return isWebsocketSubscription(event)
3033
2976
  && event?.event === exports.WebSocketSubscriptionEvent.SUBSCRIBE_GET_DATA;
3034
2977
  };
3035
- const isUnsubscribeGetDataWebSocketEventDTO = (event) => {
2978
+ const isUnsubscribeGetDataWebSocketEventDto = (event) => {
3036
2979
  return isWebsocketSubscription(event)
3037
2980
  && event?.event === exports.WebSocketSubscriptionEvent.UNSUBSCRIBE_GET_DATA;
3038
2981
  };
3039
- const isSubscribeProblemCrawledWebSocketEventDTO = (event) => {
2982
+ const isSubscribeProblemCrawledWebSocketEventDto = (event) => {
3040
2983
  return isWebsocketSubscription(event)
3041
2984
  && event?.event === exports.WebSocketSubscriptionEvent.SUBSCRIBE_PROBLEM_CRAWLED;
3042
2985
  };
3043
- const isUnsubscribeProblemCrawledWebSocketEventDTO = (event) => {
2986
+ const isUnsubscribeProblemCrawledWebSocketEventDto = (event) => {
3044
2987
  return isWebsocketSubscription(event)
3045
2988
  && event?.event === exports.WebSocketSubscriptionEvent.UNSUBSCRIBE_PROBLEM_CRAWLED;
3046
2989
  };
3047
- const isSubscribeSubmissionsCrawlWebSocketEventDTO = (event) => {
2990
+ const isSubscribeSubmissionsCrawlWebSocketEventDto = (event) => {
3048
2991
  return isWebsocketSubscription(event)
3049
2992
  && event?.event === exports.WebSocketSubscriptionEvent.SUBSCRIBE_SUBMISSIONS_CRAWL;
3050
2993
  };
3051
- const isUnsubscribeSubmissionsCrawlWebSocketEventDTO = (event) => {
2994
+ const isUnsubscribeSubmissionsCrawlWebSocketEventDto = (event) => {
3052
2995
  return isWebsocketSubscription(event)
3053
2996
  && event?.event === exports.WebSocketSubscriptionEvent.UNSUBSCRIBE_SUBMISSIONS_CRAWL;
3054
2997
  };
3055
- const isSubscribeContestChangesWebSocketEventDTO = (event) => {
2998
+ const isSubscribeContestChangesWebSocketEventDto = (event) => {
3056
2999
  return isWebsocketSubscription(event)
3057
3000
  && event?.event === exports.WebSocketSubscriptionEvent.SUBSCRIBE_CONTEST_CHANGES;
3058
3001
  };
3059
- const isUnsubscribeContestChangesWebSocketEventDTO = (event) => {
3002
+ const isUnsubscribeContestChangesWebSocketEventDto = (event) => {
3060
3003
  return isWebsocketSubscription(event)
3061
3004
  && event?.event === exports.WebSocketSubscriptionEvent.UNSUBSCRIBE_CONTEST_CHANGES;
3062
3005
  };
3063
- const isSubscribeClientTrackWebSocketEventDTO = (event) => {
3064
- return isWebsocketSubscription(event)
3065
- && event?.event === exports.WebSocketSubscriptionEvent.SUBSCRIBE_CLIENT_TRACK;
3066
- };
3067
- const isUnsubscribeClientTrackWebSocketEventDTO = (event) => {
3068
- return isWebsocketSubscription(event)
3069
- && event?.event === exports.WebSocketSubscriptionEvent.UNSUBSCRIBE_CLIENT_TRACK;
3070
- };
3071
- const isSubscribeUserNotificationWebSocketEventDTO = (event) => {
3006
+ const isSubscribeUserNotificationWebSocketEventDto = (event) => {
3072
3007
  return isWebsocketSubscription(event)
3073
3008
  && event?.event === exports.WebSocketSubscriptionEvent.SUBSCRIBE_USER_NOTIFICATION;
3074
3009
  };
3075
- const isUnsubscribeUserNotificationWebSocketEventDTO = (event) => {
3010
+ const isUnsubscribeUserNotificationWebSocketEventDto = (event) => {
3076
3011
  return isWebsocketSubscription(event)
3077
3012
  && event?.event === exports.WebSocketSubscriptionEvent.UNSUBSCRIBE_USER_NOTIFICATION;
3078
3013
  };
3079
- const isSubscribeClientTrackDataWebSocketEventDTO = (event) => {
3014
+ const isNonEmptyString = (value) => typeof value === 'string' && !!value;
3015
+ /**
3016
+ * Exactly one of `problemKey` / `contestKey` / `userId` is set.
3017
+ */
3018
+ const isSubmissionsJudgingScope = (scope) => {
3019
+ return [scope?.problemKey, scope?.contestKey, scope?.userId].filter(isNonEmptyString).length === 1;
3020
+ };
3021
+ const isSubscribeSubmissionsJudgingWebSocketEventDto = (event) => {
3080
3022
  return isWebsocketSubscription(event)
3081
- && event?.event === exports.WebSocketSubscriptionEvent.SUBSCRIBE_CLIENT_TRACK_DATA
3082
- && typeof event?.trackedClientId === 'string' && !!event.trackedClientId;
3023
+ && event?.event === exports.WebSocketSubscriptionEvent.SUBSCRIBE_SUBMISSIONS_JUDGING
3024
+ && isSubmissionsJudgingScope(event);
3083
3025
  };
3084
- const isUnsubscribeClientTrackDataWebSocketEventDTO = (event) => {
3026
+ const isUnsubscribeSubmissionsJudgingWebSocketEventDto = (event) => {
3085
3027
  return isWebsocketSubscription(event)
3086
- && event?.event === exports.WebSocketSubscriptionEvent.UNSUBSCRIBE_CLIENT_TRACK_DATA
3087
- && typeof event?.trackedClientId === 'string' && !!event.trackedClientId;
3028
+ && event?.event === exports.WebSocketSubscriptionEvent.UNSUBSCRIBE_SUBMISSIONS_JUDGING
3029
+ && isSubmissionsJudgingScope(event);
3088
3030
  };
3089
- // is WebSocketResponseEventDTO, CHANNEL_SUBSCRIBE_CLIENT
3090
- const isWebSocketResponseEventDTO = (event) => {
3031
+ // is WebSocketResponseEventDto, CHANNEL_SUBSCRIBE_CLIENT
3032
+ const isWebSocketResponseEventDto = (event) => {
3091
3033
  return Object.values(exports.WebSocketResponseEvent).includes(event?.event)
3092
3034
  && typeof event?.key === 'string'
3093
3035
  && typeof event?.connectionId === 'string'
3094
- && typeof event?.messageTimestamp === 'number' && !!event.messageTimestamp;
3095
- };
3096
- const isPongWebSocketResponseEventDTO = (event) => {
3097
- return isWebSocketResponseEventDTO(event)
3098
- && event?.event === exports.WebSocketResponseEvent.PONG
3099
- && !!event?.data;
3036
+ && typeof event?.createdAt === 'number' && !!event.createdAt;
3100
3037
  };
3101
- const isCodeRunStatusMessageWebSocketResponseEventDTO = (event) => {
3102
- return isWebSocketResponseEventDTO(event)
3038
+ const isCodeRunStatusMessageWebSocketResponseEventDto = (event) => {
3039
+ return isWebSocketResponseEventDto(event)
3103
3040
  && event?.event === exports.WebSocketResponseEvent.CODE_RUN_STATUS
3104
3041
  && typeof event?.runId === 'string' && !!event.runId
3105
3042
  && event?.status in exports.SubmissionRunStatus;
3106
3043
  };
3107
- const isSubmissionRunStatusMessageWebSocketResponseEventDTO = (event) => {
3108
- return isWebSocketResponseEventDTO(event)
3044
+ const isSubmissionRunStatusMessageWebSocketResponseEventDto = (event) => {
3045
+ return isWebSocketResponseEventDto(event)
3109
3046
  && event?.event === exports.WebSocketResponseEvent.SUBMISSION_RUN_STATUS
3110
3047
  && typeof event?.submitId === 'string' && !!event.submitId
3111
3048
  && event?.status in exports.SubmissionRunStatus
3112
3049
  && event?.verdict in exports.ProblemVerdict
3113
3050
  && typeof event?.points === 'number';
3114
3051
  };
3115
- const isUserMessageWebSocketResponseEventDTO = (event) => {
3116
- return isWebSocketResponseEventDTO(event)
3052
+ const isSubmissionJudgingWebSocketResponseEventDto = (event) => {
3053
+ return isWebSocketResponseEventDto(event)
3054
+ && event?.event === exports.WebSocketResponseEvent.SUBMISSION_JUDGING
3055
+ && isNonEmptyString(event?.submitId)
3056
+ && isNonEmptyString(event?.problemKey)
3057
+ && (event?.contestKey === null || isNonEmptyString(event?.contestKey))
3058
+ && isNonEmptyString(event?.userId)
3059
+ && typeof event?.judging === 'boolean'
3060
+ && event?.status in exports.SubmissionRunStatus
3061
+ && event?.verdict in exports.ProblemVerdict
3062
+ && typeof event?.points === 'number';
3063
+ };
3064
+ const isUserMessageWebSocketResponseEventDto = (event) => {
3065
+ return isWebSocketResponseEventDto(event)
3117
3066
  && event?.event === exports.WebSocketResponseEvent.USER_MESSAGE
3118
3067
  && typeof event?.user?.nickname === 'string' && !!event.user?.nickname
3119
3068
  && typeof event?.user?.imageUrl === 'string' && !!event.user?.imageUrl
3120
- && typeof event?.user?.company?.key === 'string' && !!event.user?.company?.key
3069
+ && typeof event?.user?.organization?.key === 'string' && !!event.user?.organization?.key
3121
3070
  && !!event?.content;
3122
3071
  };
3123
- const isSendDataWebSocketResponseEventDTO = (event) => {
3072
+ const isSendDataWebSocketResponseEventDto = (event) => {
3124
3073
  return [
3125
3074
  exports.WebSocketResponseEvent.SEND_DATA_ECS_TASK_DEFINITIONS_LIST,
3126
3075
  exports.WebSocketResponseEvent.SEND_DATA_EC2_INSTANCES_LIST,
3127
3076
  exports.WebSocketResponseEvent.SEND_DATA_ECS_TASKS_LIST,
3128
3077
  exports.WebSocketResponseEvent.SEND_DATA_SSM_SESSIONS_LIST,
3129
3078
  exports.WebSocketResponseEvent.SEND_DATA_RUN_COMMAND,
3130
- exports.WebSocketResponseEvent.SEND_DATA_CLIENT_TRACK,
3131
- exports.WebSocketResponseEvent.SEND_DATA_CHAT_COMPLETIONS,
3132
3079
  ].includes(event?.event)
3133
3080
  && typeof event?.dataId === 'string' && !!event.dataId
3134
3081
  && !!event?.content;
3135
3082
  };
3136
- const isSendDataEcsTaskDefinitionListWebSocketResponseEventDTO = (event) => {
3137
- return isWebSocketResponseEventDTO(event) && isSendDataWebSocketResponseEventDTO(event)
3083
+ const isSendDataEcsTaskDefinitionListWebSocketResponseEventDto = (event) => {
3084
+ return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
3138
3085
  && event?.event === exports.WebSocketResponseEvent.SEND_DATA_ECS_TASK_DEFINITIONS_LIST;
3139
3086
  };
3140
- const isSendDataEc2InstancesListWebSocketResponseEventDTO = (event) => {
3141
- return isWebSocketResponseEventDTO(event) && isSendDataWebSocketResponseEventDTO(event)
3087
+ const isSendDataEc2InstancesListWebSocketResponseEventDto = (event) => {
3088
+ return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
3142
3089
  && event?.event === exports.WebSocketResponseEvent.SEND_DATA_EC2_INSTANCES_LIST;
3143
3090
  };
3144
- const isSendDataEcsTasksListWebSocketResponseEventDTO = (event) => {
3145
- return isWebSocketResponseEventDTO(event) && isSendDataWebSocketResponseEventDTO(event)
3091
+ const isSendDataEcsTasksListWebSocketResponseEventDto = (event) => {
3092
+ return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
3146
3093
  && event?.event === exports.WebSocketResponseEvent.SEND_DATA_ECS_TASKS_LIST;
3147
3094
  };
3148
- const isSendDataSsmSessionsListWebSocketResponseEventDTO = (event) => {
3149
- return isWebSocketResponseEventDTO(event) && isSendDataWebSocketResponseEventDTO(event)
3095
+ const isSendDataSsmSessionsListWebSocketResponseEventDto = (event) => {
3096
+ return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
3150
3097
  && event?.event === exports.WebSocketResponseEvent.SEND_DATA_SSM_SESSIONS_LIST;
3151
3098
  };
3152
- const isSendDataRunCommandWebSocketResponseEventDTO = (event) => {
3153
- return isWebSocketResponseEventDTO(event) && isSendDataWebSocketResponseEventDTO(event)
3099
+ const isSendDataRunCommandWebSocketResponseEventDto = (event) => {
3100
+ return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
3154
3101
  && event?.event === exports.WebSocketResponseEvent.SEND_DATA_RUN_COMMAND;
3155
3102
  };
3156
- const isSendDataClientTrackWebSocketResponseEventDTO = (event) => {
3157
- return isWebSocketResponseEventDTO(event) && isSendDataWebSocketResponseEventDTO(event)
3158
- && event?.event === exports.WebSocketResponseEvent.SEND_DATA_CLIENT_TRACK;
3159
- };
3160
- const isSenDataChatCompletionsWebSocketResponseEventDTO = (event) => {
3161
- return isWebSocketResponseEventDTO(event) && isSendDataWebSocketResponseEventDTO(event)
3162
- && event?.event === exports.WebSocketResponseEvent.SEND_DATA_CHAT_COMPLETIONS;
3163
- };
3164
- const isProblemCrawledWebSocketResponseEventDTO = (event) => {
3165
- return isWebSocketResponseEventDTO(event)
3103
+ const isProblemCrawledWebSocketResponseEventDto = (event) => {
3104
+ return isWebSocketResponseEventDto(event)
3166
3105
  && event?.event === exports.WebSocketResponseEvent.PROBLEM_CRAWLED
3167
3106
  && !!event?.content;
3168
3107
  };
3169
- const isSubmissionsCrawlWebSocketResponseEventDTO = (event) => {
3170
- return isWebSocketResponseEventDTO(event)
3108
+ const isSubmissionsCrawlWebSocketResponseEventDto = (event) => {
3109
+ return isWebSocketResponseEventDto(event)
3171
3110
  && event?.event === exports.WebSocketResponseEvent.SUBMISSIONS_CRAWL
3172
3111
  && !!event?.content;
3173
3112
  };
3174
- const isContestChangesWebSocketResponseEventDTO = (event) => {
3175
- return isWebSocketResponseEventDTO(event)
3113
+ const isContestChangesWebSocketResponseEventDto = (event) => {
3114
+ return isWebSocketResponseEventDto(event)
3176
3115
  && event?.event === exports.WebSocketResponseEvent.CONTEST_CHANGES
3177
3116
  && !!event?.content;
3178
3117
  };
3179
- const isClientTrackWebSocketResponseEventDTO = (event) => {
3180
- return isWebSocketResponseEventDTO(event)
3181
- && event?.event === exports.WebSocketResponseEvent.CLIENT_TRACK;
3182
- };
3183
- const isUserNotificationWebSocketResponseEventDTO = (event) => {
3118
+ const isUserNotificationWebSocketResponseEventDto = (event) => {
3184
3119
  return [
3185
3120
  exports.WebSocketResponseEvent.USER_NOTIFICATION_SUBMISSION,
3186
3121
  exports.WebSocketResponseEvent.USER_NOTIFICATION_CONTEST_CLARIFICATION,
3187
3122
  ].includes(event?.event)
3188
3123
  && !!event?.content;
3189
3124
  };
3190
- const isUserNotificationSubmissionWebSocketResponseEventDTO = (event) => {
3191
- return isWebSocketResponseEventDTO(event) && isUserNotificationWebSocketResponseEventDTO(event)
3125
+ const isUserNotificationSubmissionWebSocketResponseEventDto = (event) => {
3126
+ return isWebSocketResponseEventDto(event) && isUserNotificationWebSocketResponseEventDto(event)
3192
3127
  && event?.event === exports.WebSocketResponseEvent.USER_NOTIFICATION_SUBMISSION;
3193
3128
  };
3194
- const isUserNotificationContestClarificationWebSocketResponseEventDTO = (event) => {
3195
- return isWebSocketResponseEventDTO(event) && isUserNotificationWebSocketResponseEventDTO(event)
3129
+ const isUserNotificationContestClarificationWebSocketResponseEventDto = (event) => {
3130
+ return isWebSocketResponseEventDto(event) && isUserNotificationWebSocketResponseEventDto(event)
3196
3131
  && event?.event === exports.WebSocketResponseEvent.USER_NOTIFICATION_CONTEST_CLARIFICATION;
3197
3132
  };
3198
3133
  // generic
3199
3134
  const getWebSocketResponseEventKey = (event, clientId, id) => {
3200
3135
  return `${event}-${clientId}-${id}`;
3201
3136
  };
3202
- const isWebSocketChannelsMessageDTO = (message) => {
3137
+ const isWebSocketChannelsMessageDto = (message) => {
3203
3138
  return Array.isArray(message?.channels)
3204
3139
  && message.channels.every((channel) => typeof channel === 'string' && !!channel)
3205
3140
  && Object.values(exports.WebSocketResponseEvent).includes(message?.event?.event);
3206
3141
  };
3207
3142
  /**
3208
3143
  * Key used by the client to dispatch a response received on a TOPIC channel to its subscribers.
3209
- * It is the same key that `getKeyWebSocketEventDTO` (base-ui) computes for the subscription.
3144
+ * It is the same key that `getKeyWebSocketEventDto` (base-ui) computes for the subscription.
3210
3145
  * Returns null when the response is not addressed to this client.
3211
3146
  */
3212
3147
  const getWebSocketResponseEventKeyOfResponse = (response, clientId) => {
3213
- if (isCodeRunStatusMessageWebSocketResponseEventDTO(response)) {
3148
+ if (isCodeRunStatusMessageWebSocketResponseEventDto(response)) {
3214
3149
  return getWebSocketResponseEventKey(exports.WebSocketResponseEvent.CODE_RUN_STATUS, clientId, response.runId);
3215
3150
  }
3216
- if (isSubmissionRunStatusMessageWebSocketResponseEventDTO(response)) {
3151
+ if (isSubmissionRunStatusMessageWebSocketResponseEventDto(response)) {
3217
3152
  return getWebSocketResponseEventKey(exports.WebSocketResponseEvent.SUBMISSION_RUN_STATUS, clientId, response.submitId);
3218
3153
  }
3219
- if (isSendDataWebSocketResponseEventDTO(response)) {
3154
+ if (isSendDataWebSocketResponseEventDto(response)) {
3220
3155
  return getWebSocketResponseEventKey(exports.WebSocketResponseEvent.SEND_DATA_, clientId, response.dataId);
3221
3156
  }
3222
- if (isContestChangesWebSocketResponseEventDTO(response)) {
3157
+ if (isContestChangesWebSocketResponseEventDto(response)) {
3223
3158
  return getWebSocketResponseEventKey(exports.WebSocketResponseEvent.CONTEST_CHANGES, clientId, response.content.contestKey);
3224
3159
  }
3225
- if (isProblemCrawledWebSocketResponseEventDTO(response)) {
3160
+ if (isProblemCrawledWebSocketResponseEventDto(response)) {
3226
3161
  return getWebSocketResponseEventKey(exports.WebSocketResponseEvent.PROBLEM_CRAWLED, clientId, response.content.problemKey);
3227
3162
  }
3228
- if (isSubmissionsCrawlWebSocketResponseEventDTO(response)) {
3163
+ if (isSubmissionsCrawlWebSocketResponseEventDto(response)) {
3229
3164
  return getWebSocketResponseEventKey(exports.WebSocketResponseEvent.SUBMISSIONS_CRAWL, clientId, join([response.content.contestKey, response.content.problemKeys]));
3230
3165
  }
3231
- if (isClientTrackWebSocketResponseEventDTO(response)) {
3232
- // the command is sent to the session channel, `key` holds the targeted client
3233
- return response.key === clientId ? getWebSocketResponseEventKey(exports.WebSocketResponseEvent.CLIENT_TRACK, clientId, '*') : null;
3234
- }
3235
- if (isUserNotificationWebSocketResponseEventDTO(response)) {
3166
+ if (isUserNotificationWebSocketResponseEventDto(response)) {
3236
3167
  return getWebSocketResponseEventKey(exports.WebSocketResponseEvent.USER_NOTIFICATION_, clientId, '*');
3237
3168
  }
3169
+ if (isSubmissionJudgingWebSocketResponseEventDto(response)) {
3170
+ // one key for every table: the same event is published on several channels (problem / contest / user) and the
3171
+ // client deduplicates it, so it is dispatched once; each table filters by the submissions it lists
3172
+ return getWebSocketResponseEventKey(exports.WebSocketResponseEvent.SUBMISSION_JUDGING, clientId, '*');
3173
+ }
3238
3174
  return null;
3239
3175
  };
3240
3176
  /**
@@ -3243,17 +3179,25 @@ const getWebSocketResponseEventKeyOfResponse = (response, clientId) => {
3243
3179
  * Ably rejects the attach if the token has no capability for the channel.
3244
3180
  */
3245
3181
  const getChannelOfWebSocketSubscribeEvent = (event) => {
3246
- if (isSubscribeSubmissionRunStatusWebSocketEventDTO(event)) {
3182
+ if (isSubscribeSubmissionRunStatusWebSocketEventDto(event)) {
3247
3183
  return CHANNEL_SUBMISSION(event.submitId);
3248
3184
  }
3249
- if (isSubscribeProblemCrawledWebSocketEventDTO(event)) {
3250
- return CHANNEL_PROBLEM(event.problemKey);
3251
- }
3252
- if (isSubscribeContestChangesWebSocketEventDTO(event) || isSubscribeSubmissionsCrawlWebSocketEventDTO(event)) {
3185
+ // SUBSCRIBE_PROBLEM_CRAWLED: the event arrives by the private user channel of who requested the crawl
3186
+ if (isSubscribeContestChangesWebSocketEventDto(event) || isSubscribeSubmissionsCrawlWebSocketEventDto(event)) {
3253
3187
  return CHANNEL_CONTEST(event.contestKey, exports.ContestChannelRole.SPECTATORS);
3254
3188
  }
3255
- if (isSubscribeClientTrackDataWebSocketEventDTO(event)) {
3256
- return CHANNEL_CLIENT_TRACK(event.trackedClientId);
3189
+ if (isSubscribeSubmissionsJudgingWebSocketEventDto(event)) {
3190
+ // the judging start/end is published on the spectators channel when it is visible to everyone; the hidden ones
3191
+ // (frozen / quiet contests) arrive by the role channels of the contest (managers) and the private user channel
3192
+ if ('problemKey' in event && event.problemKey) {
3193
+ return CHANNEL_PROBLEM(event.problemKey, exports.ProblemChannelRole.SPECTATORS);
3194
+ }
3195
+ if ('contestKey' in event && event.contestKey) {
3196
+ return CHANNEL_CONTEST(event.contestKey, exports.ContestChannelRole.SPECTATORS);
3197
+ }
3198
+ if ('userId' in event && event.userId) {
3199
+ return CHANNEL_USER_ROLE(event.userId, exports.UserChannelRole.SPECTATORS);
3200
+ }
3257
3201
  }
3258
3202
  return null;
3259
3203
  };
@@ -3261,11 +3205,23 @@ const getChannelOfWebSocketSubscribeEvent = (event) => {
3261
3205
  * Contest whose role channels the client needs (the API grants them when the token is requested with this contest).
3262
3206
  */
3263
3207
  const getContestKeyOfWebSocketSubscribeEvent = (event) => {
3264
- if (isSubscribeContestChangesWebSocketEventDTO(event) || isSubscribeSubmissionsCrawlWebSocketEventDTO(event)) {
3208
+ if (isSubscribeContestChangesWebSocketEventDto(event) || isSubscribeSubmissionsCrawlWebSocketEventDto(event)) {
3209
+ return event.contestKey;
3210
+ }
3211
+ if (isSubscribeSubmissionsJudgingWebSocketEventDto(event) && 'contestKey' in event && event.contestKey) {
3265
3212
  return event.contestKey;
3266
3213
  }
3267
3214
  return null;
3268
3215
  };
3216
+ /**
3217
+ * Problem whose role channels the client needs (the API grants them when the token is requested with this problem).
3218
+ */
3219
+ const getProblemKeyOfWebSocketSubscribeEvent = (event) => {
3220
+ if (isSubscribeSubmissionsJudgingWebSocketEventDto(event) && 'problemKey' in event && event.problemKey) {
3221
+ return event.problemKey;
3222
+ }
3223
+ return null;
3224
+ };
3269
3225
 
3270
3226
  function splitTime(timeRemaining) {
3271
3227
  const remaining = [];
@@ -3336,44 +3292,13 @@ function splitTime(timeRemaining) {
3336
3292
  // }
3337
3293
  return remaining;
3338
3294
  }
3339
- function normalizeToLocalStartOfDay(timestamp) {
3340
- const date = new Date(timestamp);
3341
- return new Date(date.getFullYear(), date.getMonth(), date.getDate());
3342
- }
3343
- function normalizeToLocalStartOfHour(timestamp) {
3344
- const date = new Date(timestamp);
3345
- return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours());
3346
- }
3347
- function normalizeToLocalStartOfMinutes(timestamp) {
3348
- const date = new Date(timestamp);
3349
- return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes());
3350
- }
3351
- function normalizeToLocalStartOfSeconds(timestamp) {
3352
- const date = new Date(timestamp);
3353
- return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes());
3354
- }
3355
- const getYears = (d) => d.getFullYear();
3356
- const getMonths = (d) => d.getFullYear() * 12 + d.getMonth();
3357
- const getDays = (d) => {
3358
- return Math.floor(normalizeToLocalStartOfDay(d).getTime() / ONE_DAY);
3359
- };
3360
- const getHours = (d) => {
3361
- return Math.floor(normalizeToLocalStartOfHour(d).getTime() / ONE_HOUR);
3362
- };
3363
- const getMinutes = (d) => {
3364
- return Math.floor(normalizeToLocalStartOfMinutes(d).getTime() / ONE_MINUTE);
3365
- };
3366
- const getSeconds = (d) => {
3367
- return Math.floor(normalizeToLocalStartOfSeconds(d).getTime() / 1000);
3368
- };
3369
- const getMilliseconds = (d) => d.getTime();
3370
3295
 
3371
- const getUserKey = (userNickname, userCompanyKey) => {
3372
- return userNickname + '|' + userCompanyKey;
3296
+ const getUserKey = (userNickname, userOrganizationKey) => {
3297
+ return userNickname + '|' + userOrganizationKey;
3373
3298
  };
3374
3299
  const getParamsOfUserKey = (userKey) => {
3375
- const [userNickname, userCompanyKey] = userKey.split('|');
3376
- return { userNickname, userCompanyKey };
3300
+ const [userNickname, userOrganizationKey] = userKey.split('|');
3301
+ return { userNickname, userOrganizationKey };
3377
3302
  };
3378
3303
  const getClientId = (sessionId, uiId) => {
3379
3304
  return `${sessionId}|${uiId}`;
@@ -3493,23 +3418,16 @@ exports.ACCEPTED_PROGRAMMING_LANGUAGES = ACCEPTED_PROGRAMMING_LANGUAGES;
3493
3418
  exports.ASPECT_RATIO = ASPECT_RATIO;
3494
3419
  exports.AssignmentState = AssignmentState;
3495
3420
  exports.AssignmentType = AssignmentType;
3496
- exports.CHANNEL_CLIENT_TRACK = CHANNEL_CLIENT_TRACK;
3497
- exports.CHANNEL_CLIENT_TRACK_ALL = CHANNEL_CLIENT_TRACK_ALL;
3498
- exports.CHANNEL_COMPANY_PRESENCE = CHANNEL_COMPANY_PRESENCE;
3499
3421
  exports.CHANNEL_CONTEST = CHANNEL_CONTEST;
3500
- exports.CHANNEL_PRESENCE_CLIENT = CHANNEL_PRESENCE_CLIENT;
3422
+ exports.CHANNEL_ORGANIZATION_PRESENCE = CHANNEL_ORGANIZATION_PRESENCE;
3501
3423
  exports.CHANNEL_PROBLEM = CHANNEL_PROBLEM;
3502
- exports.CHANNEL_PROBLEM_ALL = CHANNEL_PROBLEM_ALL;
3503
- exports.CHANNEL_PUBLISH_MESSAGES = CHANNEL_PUBLISH_MESSAGES;
3504
- exports.CHANNEL_PUBLISH_SUBSCRIPTIONS = CHANNEL_PUBLISH_SUBSCRIPTIONS;
3505
3424
  exports.CHANNEL_SESSION = CHANNEL_SESSION;
3506
3425
  exports.CHANNEL_SUBMISSION = CHANNEL_SUBMISSION;
3507
3426
  exports.CHANNEL_SUBMISSION_ALL = CHANNEL_SUBMISSION_ALL;
3508
- exports.CHANNEL_SUBSCRIBE_CLIENT = CHANNEL_SUBSCRIBE_CLIENT;
3509
- exports.CHANNEL_SUBSCRIBE_NOTIFICATIONS = CHANNEL_SUBSCRIBE_NOTIFICATIONS;
3510
3427
  exports.CHANNEL_USER = CHANNEL_USER;
3428
+ exports.CHANNEL_USER_ROLE = CHANNEL_USER_ROLE;
3429
+ exports.CHANNEL_USER_SPECTATORS_ALL = CHANNEL_USER_SPECTATORS_ALL;
3511
3430
  exports.CODE_LANGUAGE = CODE_LANGUAGE;
3512
- exports.COMPANY_PLAN = COMPANY_PLAN;
3513
3431
  exports.CONTEST_ROLE = CONTEST_ROLE;
3514
3432
  exports.CONTEST_STATUS = CONTEST_STATUS;
3515
3433
  exports.COOKIE_JUKI_SESSION_ID = COOKIE_JUKI_SESSION_ID;
@@ -3536,8 +3454,8 @@ exports.HEADER_JUKI_SECRET_TOKEN = HEADER_JUKI_SECRET_TOKEN;
3536
3454
  exports.HEADER_JUKI_VISITOR_SESSION_ID = HEADER_JUKI_VISITOR_SESSION_ID;
3537
3455
  exports.HOURS = HOURS;
3538
3456
  exports.JUDGE = JUDGE;
3539
- exports.JUKI_APP_COMPANY_KEY = JUKI_APP_COMPANY_KEY;
3540
3457
  exports.JUKI_APP_EMAIL_TEMPLATE = JUKI_APP_EMAIL_TEMPLATE;
3458
+ exports.JUKI_APP_ORGANIZATION_KEY = JUKI_APP_ORGANIZATION_KEY;
3541
3459
  exports.JkError = JkError;
3542
3460
  exports.LANGUAGE = LANGUAGE;
3543
3461
  exports.LOWERCASE_LETTERS = LOWERCASE_LETTERS;
@@ -3556,6 +3474,7 @@ exports.ONE_HOUR = ONE_HOUR;
3556
3474
  exports.ONE_MINUTE = ONE_MINUTE;
3557
3475
  exports.ONE_SECOND = ONE_SECOND;
3558
3476
  exports.ONE_WEEK = ONE_WEEK;
3477
+ exports.ORGANIZATION_PLAN = ORGANIZATION_PLAN;
3559
3478
  exports.PAGE = PAGE;
3560
3479
  exports.PAGE_SIZE = PAGE_SIZE;
3561
3480
  exports.PAGE_SIZES = PAGE_SIZES;
@@ -3601,6 +3520,13 @@ exports._SUB_TAB = _SUB_TAB;
3601
3520
  exports._TAB = _TAB;
3602
3521
  exports._TYPE = _TYPE;
3603
3522
  exports.areArraysDifferent = areArraysDifferent;
3523
+ exports.changeDay = changeDay;
3524
+ exports.changeHours = changeHours;
3525
+ exports.changeMilliseconds = changeMilliseconds;
3526
+ exports.changeMinutes = changeMinutes;
3527
+ exports.changeMonth = changeMonth;
3528
+ exports.changeSeconds = changeSeconds;
3529
+ exports.changeYear = changeYear;
3604
3530
  exports.chunkString = chunkString;
3605
3531
  exports.cleanRequest = cleanRequest;
3606
3532
  exports.clearAsyncInterval = clearAsyncInterval;
@@ -3609,6 +3535,16 @@ exports.consoleInfo = consoleInfo;
3609
3535
  exports.consoleWarn = consoleWarn;
3610
3536
  exports.contentResponse = contentResponse;
3611
3537
  exports.contentsResponse = contentsResponse;
3538
+ exports.decreaseDay = decreaseDay;
3539
+ exports.decreaseMonth = decreaseMonth;
3540
+ exports.decreaseYear = decreaseYear;
3541
+ exports.endOfDay = endOfDay;
3542
+ exports.endOfHour = endOfHour;
3543
+ exports.endOfMinute = endOfMinute;
3544
+ exports.endOfMonth = endOfMonth;
3545
+ exports.endOfSecond = endOfSecond;
3546
+ exports.endOfWeek = endOfWeek;
3547
+ exports.endOfYear = endOfYear;
3612
3548
  exports.errorsResponse = errorsResponse;
3613
3549
  exports.getAssignmentCommentKey = getAssignmentCommentKey;
3614
3550
  exports.getAssignmentUserCommentKey = getAssignmentUserCommentKey;
@@ -3629,8 +3565,10 @@ exports.getMonths = getMonths;
3629
3565
  exports.getParamsOfClientId = getParamsOfClientId;
3630
3566
  exports.getParamsOfUserKey = getParamsOfUserKey;
3631
3567
  exports.getPlainText = getPlainText;
3568
+ exports.getProblemChannelParams = getProblemChannelParams;
3632
3569
  exports.getProblemCommentKey = getProblemCommentKey;
3633
3570
  exports.getProblemJudgeKey = getProblemJudgeKey;
3571
+ exports.getProblemKeyOfWebSocketSubscribeEvent = getProblemKeyOfWebSocketSubscribeEvent;
3634
3572
  exports.getRandomString = getRandomString;
3635
3573
  exports.getSeconds = getSeconds;
3636
3574
  exports.getSummaryWorksheetsInPages = getSummaryWorksheetsInPages;
@@ -3642,69 +3580,90 @@ exports.getWebSocketResponseEventKeyOfResponse = getWebSocketResponseEventKeyOfR
3642
3580
  exports.getWorksheetsInPages = getWorksheetsInPages;
3643
3581
  exports.getYears = getYears;
3644
3582
  exports.humanFileSize = humanFileSize;
3583
+ exports.increaseDay = increaseDay;
3584
+ exports.increaseMonth = increaseMonth;
3585
+ exports.increaseYear = increaseYear;
3645
3586
  exports.indexToLetters = indexToLetters;
3587
+ exports.isAfter = isAfter;
3646
3588
  exports.isBasicWorksheet = isBasicWorksheet;
3647
- exports.isChatCompletionsWebSocketEventDTO = isChatCompletionsWebSocketEventDTO;
3648
- exports.isClientTrackDeviceWebSocketEventDTO = isClientTrackDeviceWebSocketEventDTO;
3649
- exports.isClientTrackLocationWebSocketEventDTO = isClientTrackLocationWebSocketEventDTO;
3650
- exports.isClientTrackScreenshotWebSocketEventDTO = isClientTrackScreenshotWebSocketEventDTO;
3651
- exports.isClientTrackWebSocketResponseEventDTO = isClientTrackWebSocketResponseEventDTO;
3589
+ exports.isBefore = isBefore;
3652
3590
  exports.isCodeEditorSheet = isCodeEditorSheet;
3653
- exports.isCodeRunStatusMessageWebSocketResponseEventDTO = isCodeRunStatusMessageWebSocketResponseEventDTO;
3591
+ exports.isCodeRunStatusMessageWebSocketResponseEventDto = isCodeRunStatusMessageWebSocketResponseEventDto;
3654
3592
  exports.isContestAssignment = isContestAssignment;
3655
- exports.isContestChangesWebSocketResponseEventDTO = isContestChangesWebSocketResponseEventDTO;
3593
+ exports.isContestChangesWebSocketResponseEventDto = isContestChangesWebSocketResponseEventDto;
3656
3594
  exports.isCourseAssignment = isCourseAssignment;
3595
+ exports.isDayAfter = isDayAfter;
3596
+ exports.isDayBefore = isDayBefore;
3657
3597
  exports.isEndlessContest = isEndlessContest;
3598
+ exports.isEqual = isEqual;
3658
3599
  exports.isFutureContest = isFutureContest;
3659
3600
  exports.isGlobalContest = isGlobalContest;
3601
+ exports.isHoursAfter = isHoursAfter;
3602
+ exports.isHoursBefore = isHoursBefore;
3660
3603
  exports.isJkmdSheet = isJkmdSheet;
3604
+ exports.isMillisecondsAfter = isMillisecondsAfter;
3605
+ exports.isMillisecondsBefore = isMillisecondsBefore;
3606
+ exports.isMinutesAfter = isMinutesAfter;
3607
+ exports.isMinutesBefore = isMinutesBefore;
3608
+ exports.isMonthAfter = isMonthAfter;
3609
+ exports.isMonthBefore = isMonthBefore;
3661
3610
  exports.isObjectJson = isObjectJson;
3662
3611
  exports.isPastContest = isPastContest;
3663
- exports.isPingWebSocketEventDTO = isPingWebSocketEventDTO;
3664
- exports.isPongWebSocketResponseEventDTO = isPongWebSocketResponseEventDTO;
3665
- exports.isProblemCrawledWebSocketResponseEventDTO = isProblemCrawledWebSocketResponseEventDTO;
3612
+ exports.isProblemCrawledWebSocketResponseEventDto = isProblemCrawledWebSocketResponseEventDto;
3666
3613
  exports.isQuizOptionsSheet = isQuizOptionsSheet;
3667
3614
  exports.isQuizProblemSheet = isQuizProblemSheet;
3668
3615
  exports.isQuizTextSheet = isQuizTextSheet;
3669
- exports.isSenDataChatCompletionsWebSocketResponseEventDTO = isSenDataChatCompletionsWebSocketResponseEventDTO;
3670
- exports.isSendDataClientTrackWebSocketResponseEventDTO = isSendDataClientTrackWebSocketResponseEventDTO;
3671
- exports.isSendDataEc2InstancesListWebSocketResponseEventDTO = isSendDataEc2InstancesListWebSocketResponseEventDTO;
3672
- exports.isSendDataEcsTaskDefinitionListWebSocketResponseEventDTO = isSendDataEcsTaskDefinitionListWebSocketResponseEventDTO;
3673
- exports.isSendDataEcsTasksListWebSocketResponseEventDTO = isSendDataEcsTasksListWebSocketResponseEventDTO;
3674
- exports.isSendDataRunCommandWebSocketResponseEventDTO = isSendDataRunCommandWebSocketResponseEventDTO;
3675
- exports.isSendDataSsmSessionsListWebSocketResponseEventDTO = isSendDataSsmSessionsListWebSocketResponseEventDTO;
3676
- exports.isSendDataWebSocketResponseEventDTO = isSendDataWebSocketResponseEventDTO;
3616
+ exports.isSameDay = isSameDay;
3617
+ exports.isSameHour = isSameHour;
3618
+ exports.isSameMillisecond = isSameMillisecond;
3619
+ exports.isSameMinute = isSameMinute;
3620
+ exports.isSameMonth = isSameMonth;
3621
+ exports.isSameSecond = isSameSecond;
3622
+ exports.isSameYear = isSameYear;
3623
+ exports.isSecondsAfter = isSecondsAfter;
3624
+ exports.isSecondsBefore = isSecondsBefore;
3625
+ exports.isSendDataEc2InstancesListWebSocketResponseEventDto = isSendDataEc2InstancesListWebSocketResponseEventDto;
3626
+ exports.isSendDataEcsTaskDefinitionListWebSocketResponseEventDto = isSendDataEcsTaskDefinitionListWebSocketResponseEventDto;
3627
+ exports.isSendDataEcsTasksListWebSocketResponseEventDto = isSendDataEcsTasksListWebSocketResponseEventDto;
3628
+ exports.isSendDataRunCommandWebSocketResponseEventDto = isSendDataRunCommandWebSocketResponseEventDto;
3629
+ exports.isSendDataSsmSessionsListWebSocketResponseEventDto = isSendDataSsmSessionsListWebSocketResponseEventDto;
3630
+ exports.isSendDataWebSocketResponseEventDto = isSendDataWebSocketResponseEventDto;
3677
3631
  exports.isStringJson = isStringJson;
3678
- exports.isSubmissionRunStatusMessageWebSocketResponseEventDTO = isSubmissionRunStatusMessageWebSocketResponseEventDTO;
3679
- exports.isSubmissionsCrawlWebSocketResponseEventDTO = isSubmissionsCrawlWebSocketResponseEventDTO;
3680
- exports.isSubscribeClientTrackDataWebSocketEventDTO = isSubscribeClientTrackDataWebSocketEventDTO;
3681
- exports.isSubscribeClientTrackWebSocketEventDTO = isSubscribeClientTrackWebSocketEventDTO;
3682
- exports.isSubscribeCodeRunStatusWebSocketEventDTO = isSubscribeCodeRunStatusWebSocketEventDTO;
3683
- exports.isSubscribeContestChangesWebSocketEventDTO = isSubscribeContestChangesWebSocketEventDTO;
3684
- exports.isSubscribeGetDataWebSocketEventDTO = isSubscribeGetDataWebSocketEventDTO;
3685
- exports.isSubscribeProblemCrawledWebSocketEventDTO = isSubscribeProblemCrawledWebSocketEventDTO;
3686
- exports.isSubscribeSubmissionRunStatusWebSocketEventDTO = isSubscribeSubmissionRunStatusWebSocketEventDTO;
3687
- exports.isSubscribeSubmissionsCrawlWebSocketEventDTO = isSubscribeSubmissionsCrawlWebSocketEventDTO;
3688
- exports.isSubscribeUserNotificationWebSocketEventDTO = isSubscribeUserNotificationWebSocketEventDTO;
3632
+ exports.isSubmissionJudgingWebSocketResponseEventDto = isSubmissionJudgingWebSocketResponseEventDto;
3633
+ exports.isSubmissionRunStatusMessageWebSocketResponseEventDto = isSubmissionRunStatusMessageWebSocketResponseEventDto;
3634
+ exports.isSubmissionsCrawlWebSocketResponseEventDto = isSubmissionsCrawlWebSocketResponseEventDto;
3635
+ exports.isSubmissionsJudgingScope = isSubmissionsJudgingScope;
3636
+ exports.isSubscribeCodeRunStatusWebSocketEventDto = isSubscribeCodeRunStatusWebSocketEventDto;
3637
+ exports.isSubscribeContestChangesWebSocketEventDto = isSubscribeContestChangesWebSocketEventDto;
3638
+ exports.isSubscribeGetDataWebSocketEventDto = isSubscribeGetDataWebSocketEventDto;
3639
+ exports.isSubscribeProblemCrawledWebSocketEventDto = isSubscribeProblemCrawledWebSocketEventDto;
3640
+ exports.isSubscribeSubmissionRunStatusWebSocketEventDto = isSubscribeSubmissionRunStatusWebSocketEventDto;
3641
+ exports.isSubscribeSubmissionsCrawlWebSocketEventDto = isSubscribeSubmissionsCrawlWebSocketEventDto;
3642
+ exports.isSubscribeSubmissionsJudgingWebSocketEventDto = isSubscribeSubmissionsJudgingWebSocketEventDto;
3643
+ exports.isSubscribeUserNotificationWebSocketEventDto = isSubscribeUserNotificationWebSocketEventDto;
3689
3644
  exports.isTeamMember = isTeamMember;
3690
- exports.isUnsubscribeClientTrackDataWebSocketEventDTO = isUnsubscribeClientTrackDataWebSocketEventDTO;
3691
- exports.isUnsubscribeClientTrackWebSocketEventDTO = isUnsubscribeClientTrackWebSocketEventDTO;
3692
- exports.isUnsubscribeCodeRunStatusWebSocketEventDTO = isUnsubscribeCodeRunStatusWebSocketEventDTO;
3693
- exports.isUnsubscribeContestChangesWebSocketEventDTO = isUnsubscribeContestChangesWebSocketEventDTO;
3694
- exports.isUnsubscribeGetDataWebSocketEventDTO = isUnsubscribeGetDataWebSocketEventDTO;
3695
- exports.isUnsubscribeProblemCrawledWebSocketEventDTO = isUnsubscribeProblemCrawledWebSocketEventDTO;
3696
- exports.isUnsubscribeSubmissionRunStatusWebSocketEventDTO = isUnsubscribeSubmissionRunStatusWebSocketEventDTO;
3697
- exports.isUnsubscribeSubmissionsCrawlWebSocketEventDTO = isUnsubscribeSubmissionsCrawlWebSocketEventDTO;
3698
- exports.isUnsubscribeUserNotificationWebSocketEventDTO = isUnsubscribeUserNotificationWebSocketEventDTO;
3645
+ exports.isToday = isToday;
3646
+ exports.isUnsubscribeCodeRunStatusWebSocketEventDto = isUnsubscribeCodeRunStatusWebSocketEventDto;
3647
+ exports.isUnsubscribeContestChangesWebSocketEventDto = isUnsubscribeContestChangesWebSocketEventDto;
3648
+ exports.isUnsubscribeGetDataWebSocketEventDto = isUnsubscribeGetDataWebSocketEventDto;
3649
+ exports.isUnsubscribeProblemCrawledWebSocketEventDto = isUnsubscribeProblemCrawledWebSocketEventDto;
3650
+ exports.isUnsubscribeSubmissionRunStatusWebSocketEventDto = isUnsubscribeSubmissionRunStatusWebSocketEventDto;
3651
+ exports.isUnsubscribeSubmissionsCrawlWebSocketEventDto = isUnsubscribeSubmissionsCrawlWebSocketEventDto;
3652
+ exports.isUnsubscribeSubmissionsJudgingWebSocketEventDto = isUnsubscribeSubmissionsJudgingWebSocketEventDto;
3653
+ exports.isUnsubscribeUserNotificationWebSocketEventDto = isUnsubscribeUserNotificationWebSocketEventDto;
3699
3654
  exports.isUserMember = isUserMember;
3700
- exports.isUserMessageWebSocketResponseEventDTO = isUserMessageWebSocketResponseEventDTO;
3701
- exports.isUserNotificationContestClarificationWebSocketResponseEventDTO = isUserNotificationContestClarificationWebSocketResponseEventDTO;
3702
- exports.isUserNotificationSubmissionWebSocketResponseEventDTO = isUserNotificationSubmissionWebSocketResponseEventDTO;
3703
- exports.isUserNotificationWebSocketResponseEventDTO = isUserNotificationWebSocketResponseEventDTO;
3704
- exports.isWebSocketChannelsMessageDTO = isWebSocketChannelsMessageDTO;
3705
- exports.isWebSocketResponseEventDTO = isWebSocketResponseEventDTO;
3655
+ exports.isUserMessageWebSocketResponseEventDto = isUserMessageWebSocketResponseEventDto;
3656
+ exports.isUserNotificationContestClarificationWebSocketResponseEventDto = isUserNotificationContestClarificationWebSocketResponseEventDto;
3657
+ exports.isUserNotificationSubmissionWebSocketResponseEventDto = isUserNotificationSubmissionWebSocketResponseEventDto;
3658
+ exports.isUserNotificationWebSocketResponseEventDto = isUserNotificationWebSocketResponseEventDto;
3659
+ exports.isValidDate = isValidDate;
3660
+ exports.isWebSocketChannelsMessageDto = isWebSocketChannelsMessageDto;
3661
+ exports.isWebSocketResponseEventDto = isWebSocketResponseEventDto;
3706
3662
  exports.isWebsocketSubscription = isWebsocketSubscription;
3663
+ exports.isWithinInterval = isWithinInterval;
3707
3664
  exports.isWorksheetAssignment = isWorksheetAssignment;
3665
+ exports.isYearAfter = isYearAfter;
3666
+ exports.isYearBefore = isYearBefore;
3708
3667
  exports.join = join;
3709
3668
  exports.lettersToIndex = lettersToIndex;
3710
3669
  exports.memorySizeOf = memorySizeOf;
@@ -3716,12 +3675,21 @@ exports.normalizeToLocalStartOfMinutes = normalizeToLocalStartOfMinutes;
3716
3675
  exports.normalizeToLocalStartOfSeconds = normalizeToLocalStartOfSeconds;
3717
3676
  exports.objectUpdate = objectUpdate;
3718
3677
  exports.objectsUpdate = objectsUpdate;
3678
+ exports.padEnd = padEnd;
3679
+ exports.padStart = padStart;
3719
3680
  exports.range = range;
3720
3681
  exports.removeExtension = removeExtension;
3721
3682
  exports.safeJsonParse = safeJsonParse;
3722
3683
  exports.setAsyncInterval = setAsyncInterval;
3723
3684
  exports.split = split;
3724
3685
  exports.splitTime = splitTime;
3686
+ exports.startOfDay = startOfDay;
3687
+ exports.startOfHour = startOfHour;
3688
+ exports.startOfMinute = startOfMinute;
3689
+ exports.startOfMonth = startOfMonth;
3690
+ exports.startOfSecond = startOfSecond;
3691
+ exports.startOfWeek = startOfWeek;
3692
+ exports.startOfYear = startOfYear;
3725
3693
  exports.stringToArrayBuffer = stringToArrayBuffer;
3726
- exports.toEntityMembersDTO = toEntityMembersDTO;
3694
+ exports.toEntityMembersDto = toEntityMembersDto;
3727
3695
  exports.toJkError = toJkError;