islamic-date-adjustment 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +325 -0
- package/coverage/clover.xml +215 -0
- package/coverage/coverage-final.json +3 -0
- package/coverage/lcov-report/adjustmentEngine.js.html +1795 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +131 -0
- package/coverage/lcov-report/islamicCalendar.js.html +526 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov.info +458 -0
- package/jest.config.js +6 -0
- package/package.json +50 -0
- package/src/adjustmentEngine.js +602 -0
- package/src/cli.js +343 -0
- package/src/defaults.js +21 -0
- package/src/firebaseAdapter.js +190 -0
- package/src/index.js +27 -0
- package/src/islamicCalendar.js +160 -0
- package/src/useHijriYear.js +249 -0
- package/tests/adjustmentEngine.test.js +982 -0
- package/tests/firebaseAdapter.test.js +270 -0
- package/tests/islamicCalendar.test.js +230 -0
package/README.md
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# 🕌 Islamic Date Adjustment Library
|
|
2
|
+
|
|
3
|
+
A JavaScript library for adjusting Islamic (Hijri) calendar dates based on local moon sighting, with **intelligent handling of month boundaries** and already-observed days.
|
|
4
|
+
|
|
5
|
+
Works everywhere: **React Native**, **Node.js**, **Web**, or any JavaScript environment.
|
|
6
|
+
|
|
7
|
+
## The Problem
|
|
8
|
+
|
|
9
|
+
Islamic calendar dates are determined by moon sighting, which varies by region. When an authority announces "Ramadan starts on Feb 18," your local community might sight the moon 2 days earlier (Feb 16). Later, when Eid al-Fitr is announced, you can't simply shift the entire calendar — you've already been fasting since Feb 16!
|
|
10
|
+
|
|
11
|
+
This library solves that by:
|
|
12
|
+
|
|
13
|
+
1. **Global offset** — shift the entire calendar uniformly (e.g., -2 days for your local sighting)
|
|
14
|
+
2. **Per-event adjustment** — when a specific event (Eid, Laylat al-Qadr, etc.) is confirmed on a different date, adjust only that event forward while **preserving already-passed days**
|
|
15
|
+
3. **Month-length validation** — Islamic months can only be 29 or 30 days; invalid adjustments are rejected with a clear error
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install islamic-date-adjustment
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Quick Start (React Native)
|
|
26
|
+
|
|
27
|
+
### 1. Basic usage (no persistence)
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
import { HijriYear, DEFAULT_1447_STARTS, formatDate } from 'islamic-date-adjustment';
|
|
31
|
+
|
|
32
|
+
const hy = new HijriYear(1447, DEFAULT_1447_STARTS);
|
|
33
|
+
hy.setGlobalOffset(-2); // Your local moon sighting
|
|
34
|
+
|
|
35
|
+
console.log(formatDate(hy.getMonthStart(9))); // "2026-02-15" (Ramadan)
|
|
36
|
+
console.log(formatDate(hy.getEventDate('eid_al_fitr'))); // "2026-03-17"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. With the React hook
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
import { useHijriYear, DEFAULT_1447_STARTS } from 'islamic-date-adjustment';
|
|
43
|
+
|
|
44
|
+
function RamadanScreen() {
|
|
45
|
+
const hijri = useHijriYear({
|
|
46
|
+
year: 1447,
|
|
47
|
+
monthStarts: DEFAULT_1447_STARTS,
|
|
48
|
+
globalOffset: -2,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Get valid date options for Eid (only 29–30 day month lengths)
|
|
52
|
+
const eidOptions = hijri.getValidOffsets('eid_al_fitr');
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<View>
|
|
56
|
+
<Text>Ramadan starts: {hijri.getMonthStart(9)}</Text>
|
|
57
|
+
<Text>Eid al-Fitr: {hijri.getEventDate('eid_al_fitr')}</Text>
|
|
58
|
+
<Text>Ramadan days: {hijri.getMonthDays(9)}</Text>
|
|
59
|
+
|
|
60
|
+
{eidOptions.map((opt) => (
|
|
61
|
+
<Button
|
|
62
|
+
key={opt.date}
|
|
63
|
+
title={`${opt.date} ${opt.label}`}
|
|
64
|
+
onPress={() => hijri.adjustEvent('eid_al_fitr', opt.date)}
|
|
65
|
+
/>
|
|
66
|
+
))}
|
|
67
|
+
</View>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 3. With Firebase persistence
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
import firestore from '@react-native-firebase/firestore';
|
|
76
|
+
import { useHijriYear, DEFAULT_1447_STARTS, createFirebaseAdapter } from 'islamic-date-adjustment';
|
|
77
|
+
|
|
78
|
+
const adapter = createFirebaseAdapter(firestore());
|
|
79
|
+
|
|
80
|
+
function CalendarScreen({ userId }) {
|
|
81
|
+
const hijri = useHijriYear({
|
|
82
|
+
year: 1447,
|
|
83
|
+
monthStarts: DEFAULT_1447_STARTS,
|
|
84
|
+
globalOffset: -2,
|
|
85
|
+
firebaseAdapter: adapter,
|
|
86
|
+
userId, // saves to Firestore doc: hijri_calendars/{userId}_1447
|
|
87
|
+
realtime: true, // syncs across devices
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
if (hijri.loading) return <ActivityIndicator />;
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<View>
|
|
94
|
+
<Text>Ramadan: {hijri.getMonthStart(9)} – {hijri.getMonthEnd(9)}</Text>
|
|
95
|
+
<Text>Days fasted: {hijri.getDaysObserved(9, '2026-03-10')}</Text>
|
|
96
|
+
|
|
97
|
+
<FlatList
|
|
98
|
+
data={hijri.calendar}
|
|
99
|
+
renderItem={({ item }) => (
|
|
100
|
+
<Text>{item.name}: {item.adjustedStart} ({item.adjustedDays} days)</Text>
|
|
101
|
+
)}
|
|
102
|
+
/>
|
|
103
|
+
</View>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Changes are **auto-saved** to Firestore 500ms after each adjustment (debounced).
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Firebase Adapter API
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
import { createFirebaseAdapter } from 'islamic-date-adjustment';
|
|
116
|
+
|
|
117
|
+
const adapter = createFirebaseAdapter(firestoreInstance, 'collection_name');
|
|
118
|
+
|
|
119
|
+
await adapter.save(userId, hijriYear); // Save state
|
|
120
|
+
const hy = await adapter.load(userId, 1447); // Load state (returns HijriYear or null)
|
|
121
|
+
await adapter.remove(userId, 1447); // Delete saved data
|
|
122
|
+
const years = await adapter.listYears(userId); // List all saved years
|
|
123
|
+
const unsub = adapter.onSnapshot(userId, 1447, (hy) => { ... }); // Real-time listener
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Firestore document structure
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
hijri_calendars/{userId}_{year}
|
|
130
|
+
├── year: 1447
|
|
131
|
+
├── globalOffset: -2
|
|
132
|
+
├── monthStarts: { 1: "2025-06-26", 2: "2025-07-26", ... }
|
|
133
|
+
├── adjustments: [{ eventId, targetDate, offsetDelta, ... }]
|
|
134
|
+
├── userId: "user_abc"
|
|
135
|
+
└── updatedAt: "2026-03-18T12:00:00.000Z"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Serialization helpers (for custom storage)
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
import { serialize, deserialize } from 'islamic-date-adjustment';
|
|
142
|
+
|
|
143
|
+
const json = serialize(hijriYear); // → plain JSON-safe object
|
|
144
|
+
const hy = deserialize(json); // → HijriYear instance
|
|
145
|
+
// Use these with AsyncStorage, MMKV, or any storage backend
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## useHijriYear Hook Reference
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
const hijri = useHijriYear({
|
|
154
|
+
year, // number — Hijri year (e.g. 1447)
|
|
155
|
+
monthStarts, // object — { monthIndex: "YYYY-MM-DD" }
|
|
156
|
+
globalOffset, // number — initial offset (default 0)
|
|
157
|
+
firebaseAdapter, // optional — from createFirebaseAdapter()
|
|
158
|
+
userId, // optional — required if firebaseAdapter is set
|
|
159
|
+
realtime, // optional — subscribe to real-time updates (default false)
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Returned object
|
|
164
|
+
|
|
165
|
+
| Property / Method | Type | Description |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| `year` | `number` | Hijri year |
|
|
168
|
+
| `globalOffset` | `number` | Current global offset |
|
|
169
|
+
| `adjustments` | `Array` | List of active adjustments |
|
|
170
|
+
| `calendar` | `Array` | Full 12-month calendar (reactive) |
|
|
171
|
+
| `loading` | `boolean` | `true` while loading from Firebase |
|
|
172
|
+
| `error` | `Error\|null` | Last error |
|
|
173
|
+
| `setGlobalOffset(days)` | `void` | Update global offset |
|
|
174
|
+
| `adjustEvent(eventId, date)` | `object` | Adjust event, auto-saves |
|
|
175
|
+
| `simulateAdjustment(eventId, date)` | `object` | Preview without changing state |
|
|
176
|
+
| `getValidOffsets(eventId, range?)` | `Array` | Valid date options (pre-filtered) |
|
|
177
|
+
| `getEventDate(eventId)` | `string` | Adjusted date as "YYYY-MM-DD" |
|
|
178
|
+
| `getMonthStart(index)` | `string` | Month start as "YYYY-MM-DD" |
|
|
179
|
+
| `getMonthEnd(index)` | `string` | Month end as "YYYY-MM-DD" |
|
|
180
|
+
| `getMonthDays(index)` | `number` | Days in month |
|
|
181
|
+
| `getUpcomingEvents(date, days?)` | `Array` | Events within N days |
|
|
182
|
+
| `getDaysObserved(index, date)` | `number` | Days observed in a month |
|
|
183
|
+
| `getHijriMonthForDate(date)` | `object` | Hijri date lookup |
|
|
184
|
+
| `reset()` | `void` | Reset to initial state |
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Core API (HijriYear class)
|
|
189
|
+
|
|
190
|
+
### `new HijriYear(year, monthStarts)`
|
|
191
|
+
|
|
192
|
+
| Param | Type | Description |
|
|
193
|
+
| ------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------- |
|
|
194
|
+
| `year` | `number` | Hijri year number (e.g. 1447) |
|
|
195
|
+
| `monthStarts` | `Object<number, string>` | Map of Hijri month index (1-12) → Gregorian start date (`"YYYY-MM-DD"`). Missing months are auto-computed. |
|
|
196
|
+
|
|
197
|
+
### Methods
|
|
198
|
+
|
|
199
|
+
| Method | Returns | Description |
|
|
200
|
+
| ---------------------------------------- | ------------------------- | ------------------------------------------------------ |
|
|
201
|
+
| `setGlobalOffset(days)` | `this` | Shift all months uniformly. Range: ±15 days. |
|
|
202
|
+
| `adjustEvent(eventId, date)` | `{ adjustment, message }` | Adjust a specific event to a Gregorian date. |
|
|
203
|
+
| `getValidOffsets(eventId, range?)` | `Array` | Get valid date options for an event (default ±3 days). |
|
|
204
|
+
| `simulateEventAdjustment(eventId, date)` | `Object` | Preview impact without changing state. |
|
|
205
|
+
| `getEventDate(eventId)` | `Date` | Get the adjusted Gregorian date for an event. |
|
|
206
|
+
| `getMonthStart(monthIndex)` | `Date` | Adjusted start date of a Hijri month. |
|
|
207
|
+
| `getMonthEnd(monthIndex)` | `Date` | Adjusted last day of a Hijri month. |
|
|
208
|
+
| `getMonthDays(monthIndex)` | `number` | Adjusted number of days in a month. |
|
|
209
|
+
| `getCalendar()` | `Array` | Full calendar view with all adjustments. |
|
|
210
|
+
| `getHijriMonthForDate(date)` | `Object` | Find which Hijri month a Gregorian date falls in. |
|
|
211
|
+
| `getUpcomingEvents(refDate, days?)` | `Array` | Events within N days of a reference date. |
|
|
212
|
+
| `getDaysObserved(monthIndex, refDate)` | `number` | Days observed in a month up to a date. |
|
|
213
|
+
|
|
214
|
+
### Event IDs
|
|
215
|
+
|
|
216
|
+
| ID | Name | Hijri Date |
|
|
217
|
+
| ------------------ | ---------------- | ---------------- |
|
|
218
|
+
| `islamic_new_year` | Islamic New Year | 1 Muharram |
|
|
219
|
+
| `ashura` | Day of Ashura | 10 Muharram |
|
|
220
|
+
| `mawlid` | Mawlid al-Nabi | 12 Rabi al-Awwal |
|
|
221
|
+
| `isra_miraj` | Isra and Mi'raj | 27 Rajab |
|
|
222
|
+
| `shab_e_barat` | Shab-e-Barat | 15 Shaban |
|
|
223
|
+
| `ramadan_start` | Start of Ramadan | 1 Ramadan |
|
|
224
|
+
| `laylat_al_qadr` | Laylat al-Qadr | 27 Ramadan |
|
|
225
|
+
| `eid_al_fitr` | Eid al-Fitr | 1 Shawwal |
|
|
226
|
+
| `day_of_arafah` | Day of Arafah | 9 Dhul Hijjah |
|
|
227
|
+
| `eid_al_adha` | Eid al-Adha | 10 Dhul Hijjah |
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## How Adjustments Work
|
|
232
|
+
|
|
233
|
+
### Day-1 Events (e.g., Eid al-Fitr = 1 Shawwal)
|
|
234
|
+
|
|
235
|
+
When you move Eid al-Fitr earlier by 1 day:
|
|
236
|
+
|
|
237
|
+
- **Ramadan** (previous month) is shortened by 1 day (30 → 29)
|
|
238
|
+
- **Ramadan start** remains unchanged (you already fasted those days)
|
|
239
|
+
- **Shawwal** and all subsequent months shift accordingly
|
|
240
|
+
|
|
241
|
+
```
|
|
242
|
+
Before: Ramadan (Feb 16 → Mar 17, 30 days) | Shawwal (Mar 18 →)
|
|
243
|
+
After: Ramadan (Feb 16 → Mar 16, 29 days) | Shawwal (Mar 17 →)
|
|
244
|
+
↑ unchanged ↑ 1 day earlier
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Month-Length Validation
|
|
248
|
+
|
|
249
|
+
Islamic months can only be **29 or 30 days**. Adjustments that would violate this are rejected:
|
|
250
|
+
|
|
251
|
+
```javascript
|
|
252
|
+
const hy = new HijriYear(1447, DEFAULT_1447_STARTS);
|
|
253
|
+
// Ramadan is 30 days. Moving Eid 1 day later would make it 31 — REJECTED:
|
|
254
|
+
hy.adjustEvent('eid_al_fitr', '2026-03-20');
|
|
255
|
+
// throws: "Invalid adjustment: Ramadan would have 31 days, but Islamic months must be 29–30 days."
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
`getValidOffsets()` automatically filters out invalid options, so your UI only shows dates the user can actually pick.
|
|
259
|
+
|
|
260
|
+
### Mid-Month Events (e.g., Eid al-Adha = 10 Dhul Hijjah)
|
|
261
|
+
|
|
262
|
+
When you move Eid al-Adha earlier by 1 day:
|
|
263
|
+
|
|
264
|
+
- **Dhul Qadah** (previous month) absorbs the shift (shortened by 1)
|
|
265
|
+
- **Dhul Hijjah** starts 1 day earlier (so day 10 falls on the target date)
|
|
266
|
+
- The event's month length stays the same
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Interactive CLI
|
|
271
|
+
|
|
272
|
+
For testing and exploration, a CLI is included:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
npm start
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Running Tests
|
|
281
|
+
|
|
282
|
+
```bash
|
|
283
|
+
npm test
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
137 tests across 3 test suites covering:
|
|
287
|
+
|
|
288
|
+
- ✅ Calendar data & date helpers (30 tests)
|
|
289
|
+
- ✅ Adjustment engine (93 tests) — offsets, events, validation, simulation, edge cases
|
|
290
|
+
- ✅ Firebase adapter (14 tests) — serialize/deserialize, mock Firestore CRUD, real-time
|
|
291
|
+
|
|
292
|
+
## Project Structure
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
src/
|
|
296
|
+
islamicCalendar.js — Month definitions, event catalogue, date helpers
|
|
297
|
+
adjustmentEngine.js — HijriYear class with all adjustment logic
|
|
298
|
+
defaults.js — Default 1447 AH Gregorian start dates
|
|
299
|
+
firebaseAdapter.js — Firebase Firestore persistence (serialize/deserialize/CRUD)
|
|
300
|
+
useHijriYear.js — React/React Native hook with auto-persistence
|
|
301
|
+
cli.js — Interactive command-line interface
|
|
302
|
+
index.js — Public API entry point (re-exports everything)
|
|
303
|
+
tests/
|
|
304
|
+
islamicCalendar.test.js — 30 tests for data & helpers
|
|
305
|
+
adjustmentEngine.test.js — 93 tests for the engine
|
|
306
|
+
firebaseAdapter.test.js — 14 tests for Firebase adapter
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## Imports
|
|
310
|
+
|
|
311
|
+
```javascript
|
|
312
|
+
// Everything from one place
|
|
313
|
+
import { HijriYear, useHijriYear, createFirebaseAdapter, DEFAULT_1447_STARTS, ... } from 'islamic-date-adjustment';
|
|
314
|
+
|
|
315
|
+
// Or granular imports
|
|
316
|
+
import { HijriYear } from 'islamic-date-adjustment/engine';
|
|
317
|
+
import { useHijriYear } from 'islamic-date-adjustment/hook';
|
|
318
|
+
import { createFirebaseAdapter, serialize, deserialize } from 'islamic-date-adjustment/firebase';
|
|
319
|
+
import { DEFAULT_1447_STARTS } from 'islamic-date-adjustment/defaults';
|
|
320
|
+
import { ISLAMIC_MONTHS, SPECIAL_EVENTS, formatDate, parseDate } from 'islamic-date-adjustment/calendar';
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## License
|
|
324
|
+
|
|
325
|
+
ISC
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<coverage generated="1773843279368" clover="3.2.0">
|
|
3
|
+
<project timestamp="1773843279368" name="All files">
|
|
4
|
+
<metrics statements="203" coveredstatements="198" conditionals="141" coveredconditionals="118" methods="48" coveredmethods="48" elements="392" coveredelements="364" complexity="0" loc="203" ncloc="203" packages="1" files="2" classes="2"/>
|
|
5
|
+
<file name="adjustmentEngine.js" path="/Users/mac/Projects/IslamicDateAdjustment/src/adjustmentEngine.js">
|
|
6
|
+
<metrics statements="179" coveredstatements="174" conditionals="128" coveredconditionals="105" methods="36" coveredmethods="36"/>
|
|
7
|
+
<line num="48" count="1" type="stmt"/>
|
|
8
|
+
<line num="53" count="1" type="stmt"/>
|
|
9
|
+
<line num="54" count="1" type="stmt"/>
|
|
10
|
+
<line num="69" count="92" type="stmt"/>
|
|
11
|
+
<line num="70" count="92" type="stmt"/>
|
|
12
|
+
<line num="73" count="92" type="stmt"/>
|
|
13
|
+
<line num="76" count="1104" type="stmt"/>
|
|
14
|
+
<line num="84" count="92" type="stmt"/>
|
|
15
|
+
<line num="91" count="92" type="stmt"/>
|
|
16
|
+
<line num="92" count="994" type="stmt"/>
|
|
17
|
+
<line num="93" count="6478" type="stmt"/>
|
|
18
|
+
<line num="94" count="994" type="cond" truecount="1" falsecount="1"/>
|
|
19
|
+
<line num="98" count="92" type="stmt"/>
|
|
20
|
+
<line num="99" count="1012" type="stmt"/>
|
|
21
|
+
<line num="100" count="1012" type="stmt"/>
|
|
22
|
+
<line num="101" count="1012" type="cond" truecount="4" falsecount="0"/>
|
|
23
|
+
<line num="102" count="38" type="stmt"/>
|
|
24
|
+
<line num="107" count="92" type="stmt"/>
|
|
25
|
+
<line num="108" count="1012" type="stmt"/>
|
|
26
|
+
<line num="109" count="1012" type="stmt"/>
|
|
27
|
+
<line num="110" count="1012" type="cond" truecount="4" falsecount="0"/>
|
|
28
|
+
<line num="111" count="72" type="stmt"/>
|
|
29
|
+
<line num="116" count="92" type="stmt"/>
|
|
30
|
+
<line num="123" count="156" type="stmt"/>
|
|
31
|
+
<line num="124" count="1872" type="cond" truecount="1" falsecount="1"/>
|
|
32
|
+
<line num="125" count="1872" type="stmt"/>
|
|
33
|
+
<line num="127" count="1872" type="stmt"/>
|
|
34
|
+
<line num="133" count="156" type="stmt"/>
|
|
35
|
+
<line num="134" count="2" type="cond" truecount="1" falsecount="1"/>
|
|
36
|
+
<line num="135" count="0" type="stmt"/>
|
|
37
|
+
<line num="138" count="156" type="stmt"/>
|
|
38
|
+
<line num="139" count="36" type="stmt"/>
|
|
39
|
+
<line num="159" count="36" type="stmt"/>
|
|
40
|
+
<line num="161" count="351" type="stmt"/>
|
|
41
|
+
<line num="162" count="36" type="cond" truecount="1" falsecount="1"/>
|
|
42
|
+
<line num="164" count="36" type="stmt"/>
|
|
43
|
+
<line num="167" count="36" type="stmt"/>
|
|
44
|
+
<line num="168" count="36" type="stmt"/>
|
|
45
|
+
<line num="169" count="36" type="cond" truecount="2" falsecount="0"/>
|
|
46
|
+
<line num="171" count="35" type="cond" truecount="4" falsecount="0"/>
|
|
47
|
+
<line num="174" count="24" type="stmt"/>
|
|
48
|
+
<line num="175" count="24" type="stmt"/>
|
|
49
|
+
<line num="176" count="24" type="stmt"/>
|
|
50
|
+
<line num="177" count="18" type="stmt"/>
|
|
51
|
+
<line num="180" count="18" type="stmt"/>
|
|
52
|
+
<line num="181" count="18" type="stmt"/>
|
|
53
|
+
<line num="182" count="11" type="cond" truecount="2" falsecount="0"/>
|
|
54
|
+
<line num="187" count="10" type="cond" truecount="2" falsecount="0"/>
|
|
55
|
+
<line num="188" count="9" type="stmt"/>
|
|
56
|
+
<line num="189" count="9" type="stmt"/>
|
|
57
|
+
<line num="190" count="9" type="stmt"/>
|
|
58
|
+
<line num="191" count="6" type="stmt"/>
|
|
59
|
+
<line num="192" count="6" type="stmt"/>
|
|
60
|
+
<line num="195" count="1" type="stmt"/>
|
|
61
|
+
<line num="197" count="7" type="stmt"/>
|
|
62
|
+
<line num="200" count="1" type="stmt"/>
|
|
63
|
+
<line num="201" count="1" type="stmt"/>
|
|
64
|
+
<line num="210" count="26" type="stmt"/>
|
|
65
|
+
<line num="211" count="61" type="stmt"/>
|
|
66
|
+
<line num="223" count="33" type="cond" truecount="4" falsecount="0"/>
|
|
67
|
+
<line num="224" count="9" type="stmt"/>
|
|
68
|
+
<line num="240" count="24" type="cond" truecount="2" falsecount="0"/>
|
|
69
|
+
<line num="241" count="23" type="cond" truecount="2" falsecount="0"/>
|
|
70
|
+
<line num="242" count="21" type="stmt"/>
|
|
71
|
+
<line num="243" count="21" type="stmt"/>
|
|
72
|
+
<line num="244" count="21" type="stmt"/>
|
|
73
|
+
<line num="255" count="38" type="stmt"/>
|
|
74
|
+
<line num="256" count="38" type="cond" truecount="2" falsecount="0"/>
|
|
75
|
+
<line num="258" count="37" type="stmt"/>
|
|
76
|
+
<line num="259" count="37" type="cond" truecount="1" falsecount="1"/>
|
|
77
|
+
<line num="261" count="37" type="stmt"/>
|
|
78
|
+
<line num="262" count="36" type="stmt"/>
|
|
79
|
+
<line num="264" count="36" type="cond" truecount="2" falsecount="0"/>
|
|
80
|
+
<line num="265" count="2" type="stmt"/>
|
|
81
|
+
<line num="273" count="34" type="stmt"/>
|
|
82
|
+
<line num="282" count="34" type="stmt"/>
|
|
83
|
+
<line num="285" count="34" type="stmt"/>
|
|
84
|
+
<line num="286" count="34" type="stmt"/>
|
|
85
|
+
<line num="288" count="34" type="stmt"/>
|
|
86
|
+
<line num="289" count="34" type="stmt"/>
|
|
87
|
+
<line num="292" count="9" type="stmt"/>
|
|
88
|
+
<line num="293" count="9" type="stmt"/>
|
|
89
|
+
<line num="294" count="9" type="stmt"/>
|
|
90
|
+
<line num="297" count="25" type="stmt"/>
|
|
91
|
+
<line num="308" count="6" type="stmt"/>
|
|
92
|
+
<line num="309" count="6" type="cond" truecount="2" falsecount="0"/>
|
|
93
|
+
<line num="311" count="4" type="stmt"/>
|
|
94
|
+
<line num="312" count="4" type="cond" truecount="1" falsecount="1"/>
|
|
95
|
+
<line num="315" count="40" type="stmt"/>
|
|
96
|
+
<line num="316" count="4" type="stmt"/>
|
|
97
|
+
<line num="317" count="4" type="cond" truecount="1" falsecount="1"/>
|
|
98
|
+
<line num="318" count="4" type="stmt"/>
|
|
99
|
+
<line num="321" count="4" type="stmt"/>
|
|
100
|
+
<line num="322" count="4" type="stmt"/>
|
|
101
|
+
<line num="323" count="26" type="stmt"/>
|
|
102
|
+
<line num="326" count="26" type="stmt"/>
|
|
103
|
+
<line num="327" count="26" type="cond" truecount="4" falsecount="0"/>
|
|
104
|
+
<line num="328" count="22" type="stmt"/>
|
|
105
|
+
<line num="329" count="22" type="cond" truecount="4" falsecount="0"/>
|
|
106
|
+
<line num="330" count="18" type="stmt"/>
|
|
107
|
+
<line num="334" count="26" type="stmt"/>
|
|
108
|
+
<line num="345" count="4" type="stmt"/>
|
|
109
|
+
<line num="352" count="127" type="stmt"/>
|
|
110
|
+
<line num="353" count="127" type="cond" truecount="2" falsecount="0"/>
|
|
111
|
+
<line num="355" count="1124" type="stmt"/>
|
|
112
|
+
<line num="356" count="126" type="cond" truecount="3" falsecount="1"/>
|
|
113
|
+
<line num="358" count="126" type="stmt"/>
|
|
114
|
+
<line num="365" count="780" type="stmt"/>
|
|
115
|
+
<line num="366" count="109" type="cond" truecount="2" falsecount="0"/>
|
|
116
|
+
<line num="373" count="228" type="stmt"/>
|
|
117
|
+
<line num="374" count="36" type="cond" truecount="3" falsecount="1"/>
|
|
118
|
+
<line num="375" count="36" type="stmt"/>
|
|
119
|
+
<line num="382" count="438" type="stmt"/>
|
|
120
|
+
<line num="383" count="58" type="cond" truecount="2" falsecount="0"/>
|
|
121
|
+
<line num="390" count="36" type="stmt"/>
|
|
122
|
+
<line num="399" count="360" type="stmt"/>
|
|
123
|
+
<line num="400" count="30" type="stmt"/>
|
|
124
|
+
<line num="413" count="5" type="stmt"/>
|
|
125
|
+
<line num="414" count="5" type="stmt"/>
|
|
126
|
+
<line num="415" count="27" type="stmt"/>
|
|
127
|
+
<line num="416" count="27" type="cond" truecount="4" falsecount="0"/>
|
|
128
|
+
<line num="417" count="4" type="stmt"/>
|
|
129
|
+
<line num="418" count="4" type="cond" truecount="1" falsecount="1"/>
|
|
130
|
+
<line num="419" count="4" type="stmt"/>
|
|
131
|
+
<line num="423" count="1" type="stmt"/>
|
|
132
|
+
<line num="430" count="4" type="stmt"/>
|
|
133
|
+
<line num="431" count="4" type="stmt"/>
|
|
134
|
+
<line num="433" count="4" type="stmt"/>
|
|
135
|
+
<line num="434" count="40" type="stmt"/>
|
|
136
|
+
<line num="435" count="40" type="cond" truecount="1" falsecount="1"/>
|
|
137
|
+
<line num="436" count="40" type="stmt"/>
|
|
138
|
+
<line num="437" count="40" type="cond" truecount="4" falsecount="0"/>
|
|
139
|
+
<line num="438" count="4" type="stmt"/>
|
|
140
|
+
<line num="446" count="4" type="stmt"/>
|
|
141
|
+
<line num="454" count="54" type="stmt"/>
|
|
142
|
+
<line num="455" count="6" type="cond" truecount="3" falsecount="1"/>
|
|
143
|
+
<line num="456" count="6" type="stmt"/>
|
|
144
|
+
<line num="457" count="6" type="stmt"/>
|
|
145
|
+
<line num="458" count="6" type="cond" truecount="2" falsecount="0"/>
|
|
146
|
+
<line num="459" count="4" type="stmt"/>
|
|
147
|
+
<line num="467" count="8" type="stmt"/>
|
|
148
|
+
<line num="468" count="8" type="cond" truecount="2" falsecount="0"/>
|
|
149
|
+
<line num="470" count="7" type="stmt"/>
|
|
150
|
+
<line num="471" count="7" type="cond" truecount="1" falsecount="1"/>
|
|
151
|
+
<line num="473" count="7" type="stmt"/>
|
|
152
|
+
<line num="474" count="7" type="stmt"/>
|
|
153
|
+
<line num="477" count="7" type="stmt"/>
|
|
154
|
+
<line num="487" count="7" type="cond" truecount="2" falsecount="0"/>
|
|
155
|
+
<line num="488" count="1" type="stmt"/>
|
|
156
|
+
<line num="489" count="1" type="stmt"/>
|
|
157
|
+
<line num="493" count="60" type="stmt"/>
|
|
158
|
+
<line num="496" count="6" type="stmt"/>
|
|
159
|
+
<line num="497" count="54" type="stmt"/>
|
|
160
|
+
<line num="502" count="6" type="cond" truecount="1" falsecount="1"/>
|
|
161
|
+
<line num="503" count="6" type="stmt"/>
|
|
162
|
+
<line num="504" count="6" type="stmt"/>
|
|
163
|
+
<line num="506" count="54" type="stmt"/>
|
|
164
|
+
<line num="508" count="6" type="cond" truecount="2" falsecount="0"/>
|
|
165
|
+
<line num="509" count="6" type="stmt"/>
|
|
166
|
+
<line num="518" count="6" type="stmt"/>
|
|
167
|
+
<line num="519" count="0" type="cond" truecount="0" falsecount="2"/>
|
|
168
|
+
<line num="521" count="0" type="stmt"/>
|
|
169
|
+
<line num="528" count="0" type="stmt"/>
|
|
170
|
+
<line num="530" count="0" type="stmt"/>
|
|
171
|
+
<line num="534" count="6" type="stmt"/>
|
|
172
|
+
<line num="535" count="12" type="stmt"/>
|
|
173
|
+
<line num="538" count="6" type="stmt"/>
|
|
174
|
+
<line num="544" count="25" type="cond" truecount="2" falsecount="0"/>
|
|
175
|
+
<line num="545" count="25" type="stmt"/>
|
|
176
|
+
<line num="546" count="25" type="stmt"/>
|
|
177
|
+
<line num="551" count="25" type="stmt"/>
|
|
178
|
+
<line num="552" count="25" type="cond" truecount="2" falsecount="0"/>
|
|
179
|
+
<line num="553" count="23" type="stmt"/>
|
|
180
|
+
<line num="554" count="23" type="cond" truecount="2" falsecount="0"/>
|
|
181
|
+
<line num="555" count="17" type="stmt"/>
|
|
182
|
+
<line num="559" count="6" type="stmt"/>
|
|
183
|
+
<line num="565" count="25" type="cond" truecount="1" falsecount="1"/>
|
|
184
|
+
<line num="566" count="25" type="stmt"/>
|
|
185
|
+
<line num="570" count="1" type="stmt"/>
|
|
186
|
+
</file>
|
|
187
|
+
<file name="islamicCalendar.js" path="/Users/mac/Projects/IslamicDateAdjustment/src/islamicCalendar.js">
|
|
188
|
+
<metrics statements="24" coveredstatements="24" conditionals="13" coveredconditionals="13" methods="12" coveredmethods="12"/>
|
|
189
|
+
<line num="16" count="2" type="stmt"/>
|
|
190
|
+
<line num="35" count="65" type="cond" truecount="2" falsecount="0"/>
|
|
191
|
+
<line num="36" count="586" type="cond" truecount="2" falsecount="0"/>
|
|
192
|
+
<line num="38" count="2" type="stmt"/>
|
|
193
|
+
<line num="39" count="2" type="stmt"/>
|
|
194
|
+
<line num="40" count="21" type="cond" truecount="2" falsecount="0"/>
|
|
195
|
+
<line num="48" count="2" type="stmt"/>
|
|
196
|
+
<line num="78" count="1338" type="cond" truecount="2" falsecount="0"/>
|
|
197
|
+
<line num="85" count="20" type="stmt"/>
|
|
198
|
+
<line num="96" count="1108" type="stmt"/>
|
|
199
|
+
<line num="97" count="1108" type="cond" truecount="5" falsecount="0"/>
|
|
200
|
+
<line num="98" count="1105" type="stmt"/>
|
|
201
|
+
<line num="105" count="350" type="stmt"/>
|
|
202
|
+
<line num="106" count="350" type="stmt"/>
|
|
203
|
+
<line num="107" count="350" type="stmt"/>
|
|
204
|
+
<line num="108" count="350" type="stmt"/>
|
|
205
|
+
<line num="115" count="2394" type="stmt"/>
|
|
206
|
+
<line num="116" count="2394" type="stmt"/>
|
|
207
|
+
<line num="117" count="2394" type="stmt"/>
|
|
208
|
+
<line num="124" count="172" type="stmt"/>
|
|
209
|
+
<line num="125" count="172" type="stmt"/>
|
|
210
|
+
<line num="132" count="1" type="stmt"/>
|
|
211
|
+
<line num="133" count="1" type="stmt"/>
|
|
212
|
+
<line num="136" count="2" type="stmt"/>
|
|
213
|
+
</file>
|
|
214
|
+
</project>
|
|
215
|
+
</coverage>
|