11cb0ef41Sopenharmony_ciconst isObj = val => !!val && !Array.isArray(val) && typeof val === 'object' 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst compare = (ak, bk, prefKeys) => 41cb0ef41Sopenharmony_ci prefKeys.includes(ak) && !prefKeys.includes(bk) ? -1 51cb0ef41Sopenharmony_ci : prefKeys.includes(bk) && !prefKeys.includes(ak) ? 1 61cb0ef41Sopenharmony_ci : prefKeys.includes(ak) && prefKeys.includes(bk) 71cb0ef41Sopenharmony_ci ? prefKeys.indexOf(ak) - prefKeys.indexOf(bk) 81cb0ef41Sopenharmony_ci : ak.localeCompare(bk, 'en') 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ciconst sort = (replacer, seen) => (key, val) => { 111cb0ef41Sopenharmony_ci const prefKeys = Array.isArray(replacer) ? replacer : [] 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci if (typeof replacer === 'function') 141cb0ef41Sopenharmony_ci val = replacer(key, val) 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci if (!isObj(val)) 171cb0ef41Sopenharmony_ci return val 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ci if (seen.has(val)) 201cb0ef41Sopenharmony_ci return seen.get(val) 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci const ret = Object.entries(val).sort( 231cb0ef41Sopenharmony_ci ([ak, av], [bk, bv]) => 241cb0ef41Sopenharmony_ci isObj(av) === isObj(bv) ? compare(ak, bk, prefKeys) 251cb0ef41Sopenharmony_ci : isObj(av) ? 1 261cb0ef41Sopenharmony_ci : -1 271cb0ef41Sopenharmony_ci ).reduce((set, [k, v]) => { 281cb0ef41Sopenharmony_ci set[k] = v 291cb0ef41Sopenharmony_ci return set 301cb0ef41Sopenharmony_ci }, {}) 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci seen.set(val, ret) 331cb0ef41Sopenharmony_ci return ret 341cb0ef41Sopenharmony_ci} 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_cimodule.exports = (obj, replacer, space = 2) => 371cb0ef41Sopenharmony_ci JSON.stringify(obj, sort(replacer, new Map()), space) 381cb0ef41Sopenharmony_ci + (space ? '\n' : '') 39