1import { createLogger } from "/src/utils/logger.ts"; 2const logger = createLogger("StorageUtils"); 3export function safeGetItem(key) { 4 try { 5 return localStorage.getItem(key); 6 } catch (error) { 7 logger.error(`Failed to read ${key} from localStorage`, error); 8 return null; 9 } 10} 11export function safeSetItem(key, value) { 12 try { 13 localStorage.setItem(key, value); 14 } catch (error) { 15 logger.error(`Failed to write ${key} to localStorage`, error); 16 } 17} 18// sessionStorage ë²ì â localStorage ì ëì¼í Safari Private Mode ë°©ì´. 19// (ì: ë°°ë dismiss ë í ë¨ì 기ìµì´ë¼ sessionStorage 를 ì´ë¤.) 20export function safeSessionGetItem(key) { 21 try { 22 return sessionStorage.getItem(key); 23 } catch (error) { 24 logger.error(`Failed to read ${key} from sessionStorage`, error); 25 return null; 26 } 27} 28export function safeSessionSetItem(key, value) { 29 try { 30 sessionStorage.setItem(key, value); 31 } catch (error) { 32 logger.error(`Failed to write ${key} to sessionStorage`, error); 33 } 34} 35export function safeRemoveItem(key) { 36 try { 37 localStorage.removeItem(key); 38 } catch (error) { 39 logger.error(`Failed to remove ${key} from localStorage`, error); 40 } 41} 42export function safeGetJson(key, fallback) { 43 try { 44 const raw = localStorage.getItem(key); 45 if (!raw) return fallback; 46 const parsed = JSON.parse(raw); 47 // 기본 íì ê°ë: fallbackì´ ë°°ì´ì´ë©´ parsedë ë°°ì´ì´ì´ì¼ í¨. 48 // (localStorageê° ìë/ì¸ë¶ ì¡°ìëìì ë ì± í¬ëì ë°©ì§) 49 if (Array.isArray(fallback) && !Array.isArray(parsed)) return fallback; 50 if (!Array.isArray(fallback) && typeof fallback === "object" && fallback !== null && (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))) { 51 return fallback; 52 } 53 return parsed; 54 } catch { 55 return fallback; 56 } 57} 58export function safeSetJson(key, value) { 59 try { 60 localStorage.setItem(key, JSON.stringify(value)); 61 } catch {} 62} 63 64//# sourceMappingURL=data:application/json;base64,eyJtYXBwaW5ncyI6IkFBQUEsU0FBUyxvQkFBb0I7QUFFN0IsTUFBTSxTQUFTLGFBQWEsY0FBYztBQUUxQyxPQUFPLFNBQVMsWUFBWSxLQUE0QjtDQUN0RCxJQUFJO0VBQ0YsT0FBTyxhQUFhLFFBQVEsR0FBRztDQUNqQyxTQUFTLE9BQU87RUFDZCxPQUFPLE1BQU0sa0JBQWtCLElBQUkscUJBQXFCLEtBQUs7RUFDN0QsT0FBTztDQUNUO0FBQ0Y7QUFFQSxPQUFPLFNBQVMsWUFBWSxLQUFhLE9BQXFCO0NBQzVELElBQUk7RUFDRixhQUFhLFFBQVEsS0FBSyxLQUFLO0NBQ2pDLFNBQVMsT0FBTztFQUNkLE9BQU8sTUFBTSxtQkFBbUIsSUFBSSxtQkFBbUIsS0FBSztDQUM5RDtBQUNGOzs7QUFJQSxPQUFPLFNBQVMsbUJBQW1CLEtBQTRCO0NBQzdELElBQUk7RUFDRixPQUFPLGVBQWUsUUFBUSxHQUFHO0NBQ25DLFNBQVMsT0FBTztFQUNkLE9BQU8sTUFBTSxrQkFBa0IsSUFBSSx1QkFBdUIsS0FBSztFQUMvRCxPQUFPO0NBQ1Q7QUFDRjtBQUVBLE9BQU8sU0FBUyxtQkFBbUIsS0FBYSxPQUFxQjtDQUNuRSxJQUFJO0VBQ0YsZUFBZSxRQUFRLEtBQUssS0FBSztDQUNuQyxTQUFTLE9BQU87RUFDZCxPQUFPLE1BQU0sbUJBQW1CLElBQUkscUJBQXFCLEtBQUs7Q0FDaEU7QUFDRjtBQUVBLE9BQU8sU0FBUyxlQUFlLEtBQW1CO0NBQ2hELElBQUk7RUFDRixhQUFhLFdBQVcsR0FBRztDQUM3QixTQUFTLE9BQU87RUFDZCxPQUFPLE1BQU0sb0JBQW9CLElBQUkscUJBQXFCLEtBQUs7Q0FDakU7QUFDRjtBQUVBLE9BQU8sU0FBUyxZQUFlLEtBQWEsVUFBZ0I7Q0FDMUQsSUFBSTtFQUNGLE1BQU0sTUFBTSxhQUFhLFFBQVEsR0FBRztFQUNwQyxJQUFJLENBQUMsS0FBSyxPQUFPO0VBQ2pCLE1BQU0sU0FBUyxLQUFLLE1BQU0sR0FBRzs7O0VBRzdCLElBQUksTUFBTSxRQUFRLFFBQVEsS0FBSyxDQUFDLE1BQU0sUUFBUSxNQUFNLEdBQUcsT0FBTztFQUM5RCxJQUNFLENBQUMsTUFBTSxRQUFRLFFBQVEsS0FDcEIsT0FBTyxhQUFhLFlBQ3BCLGFBQWEsU0FDWixPQUFPLFdBQVcsWUFBWSxXQUFXLFFBQVEsTUFBTSxRQUFRLE1BQU0sSUFDekU7R0FDQSxPQUFPO0VBQ1Q7RUFDQSxPQUFPO0NBQ1QsUUFBUTtFQUNOLE9BQU87Q0FDVDtBQUNGO0FBRUEsT0FBTyxTQUFTLFlBQVksS0FBYSxPQUFzQjtDQUM3RCxJQUFJO0VBQ0YsYUFBYSxRQUFRLEtBQUssS0FBSyxVQUFVLEtBQUssQ0FBQztDQUNqRCxRQUFRLENBRVI7QUFDRiIsIm5hbWVzIjpbXSwic291cmNlcyI6WyJzdG9yYWdlVXRpbHMudHMiXSwidmVyc2lvbiI6Mywic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ1N0b3JhZ2VVdGlscycpO1xuXG5leHBvcnQgZnVuY3Rpb24gc2FmZUdldEl0ZW0oa2V5OiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gbG9jYWxTdG9yYWdlLmdldEl0ZW0oa2V5KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byByZWFkICR7a2V5fSBmcm9tIGxvY2FsU3RvcmFnZWAsIGVycm9yKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2FmZVNldEl0ZW0oa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgdHJ5IHtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShrZXksIHZhbHVlKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byB3cml0ZSAke2tleX0gdG8gbG9jYWxTdG9yYWdlYCwgZXJyb3IpO1xuICB9XG59XG5cbi8vIHNlc3Npb25TdG9yYWdlIOuyhOyghCDigJQgbG9jYWxTdG9yYWdlIOyZgCDrj5nsnbztlZwgU2FmYXJpIFByaXZhdGUgTW9kZSDrsKnslrQuXG4vLyAo7JiIOiDrsLDrhIggZGlzbWlzcyDripQg7YOtIOuLqOychCDquLDslrXsnbTrnbwgc2Vzc2lvblN0b3JhZ2Ug66W8IOyTtOuLpC4pXG5leHBvcnQgZnVuY3Rpb24gc2FmZVNlc3Npb25HZXRJdGVtKGtleTogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oa2V5KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byByZWFkICR7a2V5fSBmcm9tIHNlc3Npb25TdG9yYWdlYCwgZXJyb3IpO1xuICAgIHJldHVybi
64BudWxsO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzYWZlU2Vzc2lvblNldEl0ZW0oa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgdHJ5IHtcbiAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKGtleSwgdmFsdWUpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHdyaXRlICR7a2V5fSB0byBzZXNzaW9uU3RvcmFnZWAsIGVycm9yKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2FmZVJlbW92ZUl0ZW0oa2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgdHJ5IHtcbiAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShrZXkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHJlbW92ZSAke2tleX0gZnJvbSBsb2NhbFN0b3JhZ2VgLCBlcnJvcik7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhZmVHZXRKc29uPFQ+KGtleTogc3RyaW5nLCBmYWxsYmFjazogVCk6IFQge1xuICB0cnkge1xuICAgIGNvbnN0IHJhdyA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKGtleSk7XG4gICAgaWYgKCFyYXcpIHJldHVybiBmYWxsYmFjaztcbiAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKHJhdyk7XG4gICAgLy8g6riw67O4IO2DgOyehSDqsIDrk5w6IGZhbGxiYWNr7J20IOuwsOyXtOydtOuptCBwYXJzZWTrj4Qg67Cw7Je07J207Ja07JW8IO2VqC5cbiAgICAvLyAobG9jYWxTdG9yYWdl6rCAIOyImOuPmS/smbjrtoAg7KGw7J6R65CY7JeI7J2EIOuVjCDslbEg7YGs656Y7IucIOuwqeyngClcbiAgICBpZiAoQXJyYXkuaXNBcnJheShmYWxsYmFjaykgJiYgIUFycmF5LmlzQXJyYXkocGFyc2VkKSkgcmV0dXJuIGZhbGxiYWNrO1xuICAgIGlmIChcbiAgICAgICFBcnJheS5pc0FycmF5KGZhbGxiYWNrKVxuICAgICAgJiYgdHlwZW9mIGZhbGxiYWNrID09PSAnb2JqZWN0J1xuICAgICAgJiYgZmFsbGJhY2sgIT09IG51bGxcbiAgICAgICYmICh0eXBlb2YgcGFyc2VkICE9PSAnb2JqZWN0JyB8fCBwYXJzZWQgPT09IG51bGwgfHwgQXJyYXkuaXNBcnJheShwYXJzZWQpKVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbGxiYWNrO1xuICAgIH1cbiAgICByZXR1cm4gcGFyc2VkO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsbGJhY2s7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhZmVTZXRKc29uKGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bik6IHZvaWQge1xuICB0cnkge1xuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGtleSwgSlNPTi5zdHJpbmdpZnkodmFsdWUpKTtcbiAgfSBjYXRjaCB7XG4gICAgLy8gaWdub3JlXG4gIH1cbn1cbiJdfQ==
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.