node-mac-recorder 2.21.51 → 2.21.53

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.
@@ -475,8 +475,7 @@ extern "C" NSString *ScreenCaptureKitCurrentAudioPath(void) {
475
475
  }
476
476
 
477
477
  CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
478
- MRSyncMarkAudioSample(presentationTime);
479
-
478
+
480
479
  // Wait for audio to arrive before starting screen video to prevent leading frames.
481
480
  if (MRSyncShouldHoldVideoFrame(presentationTime)) {
482
481
  return;
@@ -632,6 +631,7 @@ extern "C" NSString *ScreenCaptureKitCurrentAudioPath(void) {
632
631
  }
633
632
 
634
633
  CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
634
+ MRSyncMarkAudioSample(presentationTime);
635
635
 
636
636
  if (!g_audioWriterStarted) {
637
637
  if (![g_audioWriter startWriting]) {
package/tasks-1.md ADDED
@@ -0,0 +1,231 @@
1
+ ---
2
+ ⚠️ 1. KRITIK: Audio Cihaz Tespit ve Varsayılan Seçim Problemi
3
+
4
+ Dosya: src/audio_recorder.mm:433-491
5
+
6
+ Problem:
7
+ - Continuity Microphone (iPhone/iPad) gibi harici cihazlar macOS 14+ sistemlerde otomatik olarak varsayılan cihaz
8
+ seçilebiliyor
9
+ - Kod şu anda sadece MacBook'un dahili mikrofonunu isDefault: true olarak işaretliyor
10
+ - Ancak bazı cihazlarda (özellikle iPhone bağlı olduğunda) sistem otomatik olarak Continuity Microphone'u tercih
11
+ edebiliyor
12
+
13
+ Etkilenen Cihazlar:
14
+ - macOS 14+ ile çalışan tüm MacBook'lar
15
+ - iPhone/iPad ile Continuity özellikleri aktif olan sistemler
16
+ - Harici USB mikrofonlar takılı olanlar
17
+
18
+ Kod Bölümü:
19
+ // Lines 455-485
20
+ BOOL isBuiltIn = NO;
21
+
22
+ if ([deviceName rangeOfString:@"MacBook" options:NSCaseInsensitiveSearch].location != NSNotFound ||
23
+ [deviceName rangeOfString:@"iMac" options:NSCaseInsensitiveSearch].location != NSNotFound) {
24
+ isBuiltIn = YES;
25
+ }
26
+
27
+ // External devices should NOT be default
28
+ if ([deviceName rangeOfString:@"Continuity" options:NSCaseInsensitiveSearch].location != NSNotFound ||
29
+ [deviceName rangeOfString:@"iPhone" options:NSCaseInsensitiveSearch].location != NSNotFound) {
30
+ isBuiltIn = NO;
31
+ }
32
+
33
+ NSDictionary *info = @{
34
+ @"isDefault": @(isBuiltIn), // Only built-in devices are default
35
+ ...
36
+ };
37
+
38
+ Öneri:
39
+ - Sistem düzeyinde gerçek varsayılan cihazı sorgulamak için [AVCaptureDevice
40
+ defaultDeviceWithMediaType:AVMediaTypeAudio] kullanılmalı
41
+ - Kullanıcı tercihi belirtmemişse sistem varsayılanı kullanılmalı
42
+
43
+ ---
44
+ 🔴 2. KRITIK: macOS Sürüm Tespiti ve Framework Seçimi
45
+
46
+ Dosya: src/mac_recorder.mm:527-697
47
+
48
+ Problem:
49
+ - macOS 14 ve 15'te ScreenCaptureKit kullanmaya çalışıyor ama hata aldığında AVFoundation'a fallback yapıyor
50
+ - Ancak bazı macOS 14 cihazlarında ScreenCaptureKit çalışıyor gibi görünüp sonra hata verebiliyor (async başlatma
51
+ problemi)
52
+ - Electron ortamlarında ScreenCaptureKit varsayılan olarak tercih ediliyor ama bazı cihazlarda AVFoundation daha
53
+ stabil
54
+
55
+ Etkilenen Cihazlar:
56
+ - macOS 14.0-14.3 arası sürümler (ScreenCaptureKit hala dengesiz)
57
+ - M1/M2 Mac'ler (bazı kernel panic sorunları yaşanabilir)
58
+ - Electron uygulamaları (rendering pipeline çakışmaları)
59
+
60
+ Kod Bölümü:
61
+ // Lines 559-576
62
+ BOOL tryScreenCaptureKit = (isM14Plus || isM15Plus) && !forceAVFoundationEnv;
63
+
64
+ if (tryScreenCaptureKit) {
65
+ if (isElectron) {
66
+ MRLog(@"⚡ ELECTRON: macOS 14+ → trying ScreenCaptureKit first");
67
+ }
68
+
69
+ @try {
70
+ if (@available(macOS 12.3, *)) {
71
+ if ([ScreenCaptureKitRecorder isScreenCaptureKitAvailable]) {
72
+ // ScreenCaptureKit başarısız olursa AVFoundation'a fallback yapıyor
73
+ // Ancak async başlatma sırasında sorunlar olabilir
74
+
75
+ Potansiyel Sorun:
76
+ - ScreenCaptureKit başlatma süresi cihazlar arası çok değişken (150ms - 2000ms)
77
+ - Kodda 600ms timeout var ama bazı cihazlarda yeterli olmayabilir
78
+
79
+ ---
80
+ ⚠️ 3. Kamera Capture Timeout Problemi
81
+
82
+ Dosya: src/mac_recorder.mm:152-176
83
+
84
+ Problem:
85
+ - Kamera başlatma için 8 saniye timeout var
86
+ - Continuity Camera (iPhone/iPad kamera) kullanılırken bu timeout yetersiz kalabiliyor
87
+ - Özellikle Wi-Fi bağlantısı zayıf olduğunda veya Bluetooth üzerinden bağlantı yapılıyorsa
88
+
89
+ Etkilenen Cihazlar:
90
+ - Continuity Camera kullanan tüm cihazlar
91
+ - Zayıf Wi-Fi/Bluetooth bağlantısı olan ortamlar
92
+ - USB kameralar (bazı yavaş başlayan modeller)
93
+
94
+ Kod Bölümü:
95
+ // Lines 163-174
96
+ double cameraWaitTimeout = 8.0; // allow slower devices
97
+ if (!waitForCameraRecordingStart(cameraWaitTimeout)) {
98
+ double cameraStartTs = currentCameraRecordingStartTime();
99
+ if (cameraStartTs > 0 || isCameraRecording()) {
100
+ MRLog(@"⚠️ Camera did not confirm start within %.1fs but appears to be running; continuing",
101
+ cameraWaitTimeout);
102
+ return true;
103
+ }
104
+ MRLog(@"❌ Camera did not signal recording start within %.1fs", cameraWaitTimeout);
105
+ stopCameraRecording();
106
+ return false;
107
+ }
108
+
109
+ ---
110
+ 🟡 4. Çoklu Ekran (Multi-Display) Koordinat Dönüşüm Hataları
111
+
112
+ Dosya: index.js:363-575
113
+
114
+ Problem:
115
+ - Farklı çözünürlük ve ölçeklendirme faktörüne sahip ekranlarda koordinat hesaplamaları hatalı olabiliyor
116
+ - Retina ekranlar vs standart ekranlar karışık kullanıldığında piksel ölçekleme tutarsızlıkları
117
+ - Negatif koordinatlar (secondary display sol tarafta olduğunda) doğru işlenmiyor olabilir
118
+
119
+ Etkilenen Cihazlar:
120
+ - MacBook + Harici monitör kombinasyonları
121
+ - Farklı DPI/scaling'e sahip çoklu ekran kurulumları
122
+ - Secondary display sol/üst tarafta konumlandırılmış sistemler
123
+
124
+ Kod Bölümü:
125
+ // Lines 476-495
126
+ const isRelativeToDisplay = () => {
127
+ const endX = parsedArea.x + parsedArea.width;
128
+ const endY = parsedArea.y + parsedArea.height;
129
+ return (
130
+ parsedArea.x >= -tolerance &&
131
+ parsedArea.y >= -tolerance &&
132
+ endX <= targetRect.width + tolerance &&
133
+ endY <= targetRect.height + tolerance
134
+ );
135
+ };
136
+
137
+ Risk:
138
+ - 1 piksel tolerance çok küçük olabilir (Retina ekranlarda 2x ölçekleme)
139
+
140
+ ---
141
+ 🟡 5. Audio Format Uyumluluk Problemi
142
+
143
+ Dosya: src/audio_recorder.mm:106-151
144
+
145
+ Problem:
146
+ - Ses formatı otomatik tespit ediliyor ama varsayılan değerler sabit kodlanmış
147
+ - Bazı harici ses kartları/cihazlar 48kHz yerine 44.1kHz veya 96kHz kullanıyor
148
+ - Kanal sayısı 1-2 arasına zorlanıyor, bazı profesyonel cihazlar daha fazla kanal sunuyor
149
+
150
+ Etkilenen Cihazlar:
151
+ - Profesyonel USB ses arayüzleri (Focusrite, PreSonus, etc.)
152
+ - Bazı Bluetooth mikrofonlar (codec limitations)
153
+ - Eski harici ses kartları (44.1kHz native)
154
+
155
+ Kod Bölümü:
156
+ // Lines 109-134
157
+ double sampleRate = asbd ? asbd->mSampleRate : 48000.0; // Default to 48kHz
158
+ NSUInteger channels = asbd ? asbd->mChannelsPerFrame : 1;
159
+ channels = MAX((NSUInteger)1, channels);
160
+
161
+ // CRITICAL FIX: Force to mono or stereo
162
+ NSUInteger validChannels = (channels <= 1) ? 1 : 2; // Force to mono or stereo
163
+ audioSettings[AVNumberOfChannelsKey] = @(validChannels);
164
+
165
+ Risk:
166
+ - 4-8 kanallı profesyonel ses arayüzlerinde veri kaybı
167
+
168
+ ---
169
+ 🔴 6. ScreenCaptureKit Async Cleanup Race Condition
170
+
171
+ Dosya: src/mac_recorder.mm:256-263
172
+
173
+ Problem:
174
+ - ScreenCaptureKit'in async cleanup mekanizması kontrol ediliyor ama hala race condition riski var
175
+ - Ardışık kayıt başlatma işlemlerinde önceki kayıt henüz tam temizlenmemiş olabiliyor
176
+
177
+ Etkilenen Cihazlar:
178
+ - Tüm macOS 14+ cihazlar (ScreenCaptureKit kullananlar)
179
+ - Hızlı start/stop yapan kullanıcılar
180
+
181
+ Kod Bölümü:
182
+ // Lines 256-263
183
+ if (@available(macOS 12.3, *)) {
184
+ extern BOOL isScreenCaptureKitCleaningUp();
185
+ if (isScreenCaptureKitCleaningUp()) {
186
+ MRLog(@"⚠️ ScreenCaptureKit is still stopping previous recording - please wait");
187
+ return Napi::Boolean::New(env, false);
188
+ }
189
+ }
190
+
191
+ ---
192
+ 🟠 7. File Format Compatibility (WebM vs MOV)
193
+
194
+ Dosya: src/audio_recorder.mm:60-97
195
+
196
+ Problem:
197
+ - macOS 15+ için WebM format tercih ediliyor ama bazı sistemlerde WebM encoder çalışmıyor
198
+ - Fallback MOV formatına geçiyor ama bu durumda dosya uzantısı tutarsızlığı oluşuyor
199
+
200
+ Etkilenen Cihazlar:
201
+ - macOS 15.0-15.1 (WebM encoder bazı cihazlarda eksik)
202
+ - Sandbox'lanmış uygulamalar (codec access restrictions)
203
+
204
+ ---
205
+ 📊 Özet: Cihaz Kategorilerine Göre Risk Matrisi
206
+
207
+ | Cihaz Kategorisi | Ana Riskler | Öncelik |
208
+ |-----------------------------------|--------------------------------------------------------|-----------|
209
+ | MacBook Pro M1/M2 + macOS 14 | ScreenCaptureKit instability, Audio device auto-switch | 🔴 Yüksek |
210
+ | MacBook + Harici Ekran | Multi-display coordinate bugs, scaling issues | 🟡 Orta |
211
+ | Continuity Camera/Mic Kullananlar | Timeout issues, network latency | 🟡 Orta |
212
+ | Profesyonel Ses Ekipmanı Olanlar | Audio format mismatch, sample rate issues | 🟡 Orta |
213
+ | Electron Uygulamaları | ScreenCaptureKit rendering conflicts | 🔴 Yüksek |
214
+ | macOS 13 Sistemler | AVFoundation limitations, feature parity | 🟢 Düşük |
215
+
216
+ ---
217
+ 💡 Öneriler
218
+
219
+ 1. Audio cihaz seçimi: Sistem varsayılanını kullanmak yerine explicit device selection zorunlu tutulmalı
220
+ 2. ScreenCaptureKit timeout: 600ms yerine 1500ms'ye çıkarılmalı veya adaptive timeout kullanılmalı
221
+ 3. Multi-display: Pixel scaling factor (backingScaleFactor) hesaplamalara dahil edilmeli
222
+ 4. Camera timeout: Continuity Camera için 15 saniye timeout uygulanmalı
223
+ 5. Format selection: WebM yerine MOV varsayılan yapılmalı (daha geniş uyumluluk)
224
+
225
+ ⏺ Analiz tamamlandı! Özetlemek gerekirse:
226
+
227
+ En kritik problemler:
228
+ 1. ☢️ Continuity/Harici ses cihazlarının otomatik varsayılan seçilmesi - Kullanıcı beklemediği mikrofon
229
+ kullanılabilir
230
+ 2. ☢️ ScreenCaptureKit async başlatma race condition - Ardışık kayıtlarda başlatma hataları
231
+ 3. ⚠️ Çoklu ekran koordinat hesaplamaları - Retina + standart ekran kombinasyonlarında yanlış bölge
package/tasks-2.md ADDED
@@ -0,0 +1,220 @@
1
+ 🔴 KRITIK BUG BULUNDU: Area Recording Tam Ekranı Kaydediyor!
2
+
3
+ Evet, ciddi bir bug var - belirtilen alan yerine tam ekranı kaydediyor olabilir. İşte analiz:
4
+
5
+ ---
6
+ 🐛 Bug #1: ScreenCaptureKit - sourceRect Bounds Validation Hatası
7
+
8
+ Dosya: src/screen_capture_kit.mm:1542-1554
9
+
10
+ Problem:
11
+ if (displayRelativeX >= 0 && displayRelativeY >= 0 &&
12
+ displayRelativeX + cropWidth <= displayBounds.size.width &&
13
+ displayRelativeY + cropHeight <= displayBounds.size.height) {
14
+ CGRect sourceRect = CGRectMake(displayRelativeX, displayRelativeY, cropWidth, cropHeight);
15
+ streamConfig.sourceRect = sourceRect;
16
+ MRLog(@"✂️ Crop sourceRect applied: ...");
17
+ } else {
18
+ NSLog(@"❌ Crop coordinates out of display bounds - skipping crop");
19
+ // ⚠️ BURADA sourceRect SET EDİLMİYOR!
20
+ }
21
+
22
+ Sorun:
23
+ - Koordinatlar display bounds dışındaysa sourceRect hiç set edilmiyor
24
+ - Bu durumda ScreenCaptureKit tam ekranı kaydediyor (default behavior)
25
+ - Hata log'u atıyor ama kayıt devam ediyor, kullanıcı fark etmiyor!
26
+
27
+ Bu ne zaman oluşur:
28
+ 1. ✅ Koordinatlar 0.1 piksel bile bounds'un dışındaysa
29
+ 2. ✅ Floating point precision hataları (örn: 1920.0000000001)
30
+ 3. ✅ Retina display scaling hesaplamaları yanlışsa
31
+ 4. ✅ Çoklu ekran sistemlerinde display-relative dönüşüm yanlışsa
32
+
33
+ ---
34
+ 🐛 Bug #2: Bounds Check'te Floating Point Precision Problemi
35
+
36
+ Kod:
37
+ if (displayRelativeX >= 0 && displayRelativeY >= 0 &&
38
+ displayRelativeX + cropWidth <= displayBounds.size.width &&
39
+ displayRelativeY + cropHeight <= displayBounds.size.height)
40
+
41
+ Sorun:
42
+ - <= strict comparison kullanıyor
43
+ - Floating point hesaplamalardan sonra 1920.0000000001 gibi değerler 1920.0 ile eşleşmiyor
44
+ - JavaScript'ten gelen koordinatlar Math.round() ile yuvarlanmış olabilir ama native tarafta double precision
45
+ kullanılıyor
46
+
47
+ Örnek:
48
+ // JavaScript (index.js)
49
+ captureArea: { x: 0, y: 0, width: 1920, height: 1080 } // Integer
50
+
51
+ // Native (Objective-C)
52
+ CGFloat cropWidth = [captureRect[@"width"] doubleValue]; // 1920.0
53
+ CGFloat displayWidth = displayBounds.size.width; // 1920.0000000001 (floating point)
54
+
55
+ // Comparison FAILS!
56
+ if (0 + 1920.0 <= 1920.0000000001) // TRUE
57
+
58
+ Ancak dikkat:
59
+ - Display dimensions genelde exact integers (1920x1080)
60
+ - ANCAK Retina ekranlarda logical size / 2 = 960.0 gibi değerler oluşabilir
61
+ - Çoklu ekranlarda farklı scaling faktörleri koordinat dönüşümlerini bozabilir
62
+
63
+ ---
64
+ 🐛 Bug #3: Koordinat Dönüşüm Zinciri Problemi
65
+
66
+ Akış:
67
+ 1. JavaScript (index.js:363-575) - Global koordinatları display-relative'e çeviriyor
68
+ 2. Native StartRecording (mac_recorder.mm:296) - CGRect olarak alıyor
69
+ 3. ScreenCaptureKit (screen_capture_kit.mm:1530) - Display-relative olarak kabul ediyor
70
+
71
+ Potansiyel Problem Noktaları:
72
+
73
+ 3a) JavaScript Normalizasyon Hatası
74
+
75
+ index.js:476-486:
76
+ const tolerance = 1; // 1 pixel tolerance
77
+ const isRelativeToDisplay = () => {
78
+ const endX = parsedArea.x + parsedArea.width;
79
+ const endY = parsedArea.y + parsedArea.height;
80
+ return (
81
+ parsedArea.x >= -tolerance &&
82
+ parsedArea.y >= -tolerance &&
83
+ endX <= targetRect.width + tolerance &&
84
+ endY <= targetRect.height + tolerance
85
+ );
86
+ };
87
+
88
+ Sorun:
89
+ - 1 pixel tolerance çok küçük olabilir!
90
+ - Retina ekranlarda logical vs physical pixel karışıklığı
91
+ - -tolerance negatif koordinatlara izin veriyor ama native kod >= 0 bekliyor
92
+
93
+ 3b) Clamping/Clipping Yetersizliği
94
+
95
+ index.js:509-527:
96
+ if (relativeX < 0) {
97
+ relativeWidth += relativeX; // Width'i azaltıyor
98
+ relativeX = 0;
99
+ }
100
+ // Height için benzer
101
+
102
+ Sorun:
103
+ - Clipping yapıyor ama sonuç <= bounds check'ini geçemeyebilir
104
+ - Örnek: x=0, width=1920.5 → bounds check fail → tam ekran kaydedilir
105
+
106
+ ---
107
+ 🐛 Bug #4: AVFoundation'da Daha Büyük Sorun - Varsayılan Full Screen
108
+
109
+ Dosya: src/avfoundation_recorder.mm:233-236
110
+
111
+ } else {
112
+ g_avCaptureRect = CGRectZero; // Full screen
113
+ NSLog(@"🖥️ Full screen capture using physical dimensions ...");
114
+ }
115
+
116
+ Sorun:
117
+ - CGRectIsEmpty(captureRect) check'i var
118
+ - ANCAK JavaScript'ten CGRectNull gelirse (boş alan), bu check FALSE döner
119
+ - CGRectNull vs CGRectZero vs CGRectEmpty karışıklığı
120
+
121
+ JavaScript tarafından gönderilen değer:
122
+ // mac_recorder.mm:269
123
+ CGRect captureRect = CGRectNull; // Default değer
124
+
125
+ // Eğer options.captureArea yoksa:
126
+ if (!CGRectIsNull(captureRect)) {
127
+ sckConfig[@"captureRect"] = @{ ... }; // Bu ÇALIŞMAZ, captureRect NULL!
128
+ }
129
+
130
+ Sonuç:
131
+ - captureRect set edilmezse ScreenCaptureKit/AVFoundation full screen kaydeder
132
+
133
+ ---
134
+ 🎯 Root Cause: Multi-Step Validation Eksikliği
135
+
136
+ Koordinat doğrulama 3 farklı yerde yapılıyor ama tutarsız:
137
+
138
+ 1. ✅ JavaScript (index.js) - Normalize ediyor, clamp ediyor
139
+ 2. ❌ ScreenCaptureKit - Strict bounds check, fail ederse sourceRect yok → full screen
140
+ 3. ⚠️ AVFoundation - Scaling yapıyor ama validation eksik
141
+
142
+ ---
143
+ 🔬 Tespit Yöntemi
144
+
145
+ Bu bug'ı şu şekilde tespit edebilirsin:
146
+
147
+ const recorder = new MacRecorder();
148
+
149
+ // Test case: Display bounds'un HEMEN dışında bir alan
150
+ const displays = await recorder.getDisplays();
151
+ const mainDisplay = displays.find(d => d.isPrimary);
152
+
153
+ await recorder.startRecording('test.mov', {
154
+ displayId: mainDisplay.id,
155
+ captureArea: {
156
+ x: 0,
157
+ y: 0,
158
+ width: mainDisplay.width + 0.5, // 0.5 piksel daha fazla!
159
+ height: mainDisplay.height
160
+ }
161
+ });
162
+
163
+ Beklenen: Kırpılmış/hatalı alan kaydedilmeli
164
+ Gerçekte Oluyor: Tam ekran kaydediliyor (sourceRect skip ediliyor)
165
+
166
+ ---
167
+ ✅ Çözüm Önerileri
168
+
169
+ Fix #1: Tolerance Ekle (ScreenCaptureKit)
170
+
171
+ // Line 1542'de
172
+ const CGFloat CROP_TOLERANCE = 2.0; // 2 pixel tolerance
173
+
174
+ if (displayRelativeX >= -CROP_TOLERANCE &&
175
+ displayRelativeY >= -CROP_TOLERANCE &&
176
+ displayRelativeX + cropWidth <= displayBounds.size.width + CROP_TOLERANCE &&
177
+ displayRelativeY + cropHeight <= displayBounds.size.height + CROP_TOLERANCE) {
178
+
179
+ // Clamp coordinates to valid range
180
+ displayRelativeX = MAX(0, displayRelativeX);
181
+ displayRelativeY = MAX(0, displayRelativeY);
182
+ cropWidth = MIN(cropWidth, displayBounds.size.width - displayRelativeX);
183
+ cropHeight = MIN(cropHeight, displayBounds.size.height - displayRelativeY);
184
+
185
+ CGRect sourceRect = CGRectMake(displayRelativeX, displayRelativeY, cropWidth, cropHeight);
186
+ streamConfig.sourceRect = sourceRect;
187
+ } else {
188
+ NSLog(@"❌ CRITICAL: Crop coordinates SIGNIFICANTLY out of bounds - ABORTING recording");
189
+ // Kayıt başlatmayı reddet, hata döndür
190
+ SCKFailScheduling();
191
+ return;
192
+ }
193
+
194
+ Fix #2: JavaScript Tolerance Artır
195
+
196
+ // index.js:476
197
+ const tolerance = 3; // Retina ekranlar için daha büyük tolerance
198
+
199
+ Fix #3: Varsayılan Davranışı Değiştir
200
+
201
+ // Bounds check fail ederse TAM EKRAN yerine HATA DÖNDÜR
202
+ NSLog(@"❌ Invalid crop coordinates - refusing to record");
203
+ *error = [NSError errorWithDomain:@"ScreenCapture"
204
+ code:-1
205
+ userInfo:@{NSLocalizedDescriptionKey: @"Crop area out of display bounds"}];
206
+ return NO; // Recording başarısız
207
+
208
+ ---
209
+ 📝 Sonuç
210
+
211
+ EVET, ciddi bir bug var:
212
+ - ✅ Area recording bounds check'i fail ederse tam ekran kaydediyor
213
+ - ✅ Floating point precision hataları check'i fail ettiriyor
214
+ - ✅ Kullanıcı bilgilendirilmiyor (sadece log)
215
+ - ✅ JavaScript'ten gelen koordinatlar native validation'dan geçemeyebiliyor
216
+
217
+ En riskli senaryolar:
218
+ 1. Retina display + area recording
219
+ 2. Çoklu ekran + area recording
220
+ 3. 0.5 piksel hassasiyetle alan seçimi (UI'dan gelebilir)