"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
    return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SlowQueryManager = void 0;
exports.registerSlowQueryManagerDependencies = registerSlowQueryManagerDependencies;
exports.ensureSlowQueryManager = ensureSlowQueryManager;
var resolveio_server_app_1 = require("../resolveio-server-app");
var common_1 = require("../util/common");
var crypto_1 = require("crypto");
var slow_query_report_1 = require("../types/slow-query-report");
var SlowQueryLogs = null;
var configuredSlowQueryManagerDependencies = null;
function resolveSlowQueryManagerDependencies(overrides) {
    var resolved = __assign(__assign({}, (configuredSlowQueryManagerDependencies || {})), (overrides || {}));
    if (!resolved.SlowQueryLogs) {
        throw new Error('SlowQueryManager dependencies are not configured.');
    }
    return resolved;
}
function applySlowQueryManagerDependencies(dependencies) {
    configuredSlowQueryManagerDependencies = dependencies;
    SlowQueryLogs = dependencies.SlowQueryLogs;
}
function registerSlowQueryManagerDependencies(dependencies) {
    applySlowQueryManagerDependencies(dependencies);
    ensureSlowQueryManager();
}
var OBJECT_ID_PATTERN = /^[a-f0-9]{24}$/i;
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
var ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}(?:[tT ][\d:.+-]+)?(?:[zZ]|[+-]\d{2}:?\d{2})?$/;
var NUMERIC_STRING_PATTERN = /^[-+]?\d+(?:\.\d+)?$/;
var TOKEN_LIKE_PATTERN = /^[A-Za-z0-9._-]{16,}$/;
var DATE_HINT_KEY_PATTERN = /(date|time|timestamp|created|updated|expires|expiry|start|end|at)$/i;
var ID_HINT_KEY_PATTERN = /(^|_)(id|uuid|guid|token|hash|key)$/i;
var SlowQueryManager = /** @class */ (function () {
    function SlowQueryManager(serverConfig, dependencies) {
        var resolvedDependencies = resolveSlowQueryManagerDependencies(dependencies);
        applySlowQueryManagerDependencies(resolvedDependencies);
        this.serverConfig = serverConfig || {};
        this.config = this.resolveConfig();
    }
    SlowQueryManager.prototype.isReady = function () {
        return !!this.config.enabled;
    };
    SlowQueryManager.prototype.validateIngestKey = function (candidate) {
        var keys = Array.isArray(this.config.ingestKeys) ? this.config.ingestKeys.filter(Boolean) : [];
        if (!keys.length) {
            return true;
        }
        if (!candidate) {
            return false;
        }
        return keys.includes(candidate.trim());
    };
    SlowQueryManager.prototype.ingestSlowQuery = function (payload) {
        return __awaiter(this, void 0, void 0, function () {
            var now, rawFilterValue, rawPipelineValue, rawOptionsValue, provisionalFingerprint, provisionalScopeKey, existing, existingOccurrences, occurrences, existingAvg, totalDuration, avgDuration, previousMax, maxBase, maxDuration, resolvedStatus, resolvedIgnored, filterValue, pipelineValue, optionsValue, explainPlanValue, explainStatsValue, explainGeneratedAtValue, fingerprintScopeKey, canonicalFingerprint, setFields, cleaned, doc;
            var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
            return __generator(this, function (_v) {
                switch (_v.label) {
                    case 0:
                        if (!this.isReady()) {
                            throw new Error('SlowQueryManager is not enabled.');
                        }
                        if (!payload || !payload.queryHash || !payload.collection || typeof payload.durationMs !== 'number' || Number.isNaN(payload.durationMs)) {
                            throw new Error('Invalid slow query payload.');
                        }
                        now = new Date();
                        rawFilterValue = (_a = payload.filter) !== null && _a !== void 0 ? _a : {};
                        rawPipelineValue = Array.isArray(payload.pipeline) ? payload.pipeline : undefined;
                        rawOptionsValue = payload.options;
                        provisionalFingerprint = this.buildCanonicalFingerprint(payload.collection, rawFilterValue, rawPipelineValue, rawOptionsValue);
                        provisionalScopeKey = this.buildFingerprintScopeKey({
                            clientSlug: payload.clientSlug,
                            clientName: payload.clientName,
                            sourceApp: payload.sourceApp,
                            environment: payload.environment,
                            publication: payload.publication,
                            serverUrl: payload.server_url
                        });
                        return [4 /*yield*/, SlowQueryLogs.findOne({
                                collection: payload.collection,
                                canonical_fingerprint_hash: provisionalFingerprint.hash,
                                fingerprint_scope_key: provisionalScopeKey
                            })];
                    case 1:
                        existing = _v.sent();
                        if (!!existing) return [3 /*break*/, 3];
                        return [4 /*yield*/, SlowQueryLogs.findOne(this.buildLegacyDedupeQuery(payload))];
                    case 2:
                        existing = _v.sent();
                        _v.label = 3;
                    case 3:
                        existingOccurrences = typeof (existing === null || existing === void 0 ? void 0 : existing.occurrences) === 'number' ? existing.occurrences : 0;
                        occurrences = existingOccurrences + 1;
                        existingAvg = typeof (existing === null || existing === void 0 ? void 0 : existing.avg_duration_ms) === 'number' ? existing.avg_duration_ms : 0;
                        totalDuration = existingAvg * existingOccurrences;
                        avgDuration = (totalDuration + payload.durationMs) / occurrences;
                        previousMax = typeof (existing === null || existing === void 0 ? void 0 : existing.max_duration_ms) === 'number' ? existing.max_duration_ms : payload.durationMs;
                        maxBase = Math.max(payload.durationMs, previousMax);
                        maxDuration = typeof payload.maxDurationMs === 'number'
                            ? Math.max(maxBase, payload.maxDurationMs)
                            : maxBase;
                        resolvedStatus = payload.status && slow_query_report_1.slowQueryLogStatuses.includes(payload.status)
                            ? payload.status
                            : ((existing === null || existing === void 0 ? void 0 : existing.status) || 'new');
                        resolvedIgnored = typeof payload.ignored === 'boolean'
                            ? payload.ignored
                            : (typeof (existing === null || existing === void 0 ? void 0 : existing.ignored) === 'boolean' ? existing.ignored : false);
                        filterValue = (_c = (_b = payload.filter) !== null && _b !== void 0 ? _b : existing === null || existing === void 0 ? void 0 : existing.filter) !== null && _c !== void 0 ? _c : {};
                        pipelineValue = Array.isArray(payload.pipeline)
                            ? payload.pipeline
                            : existing === null || existing === void 0 ? void 0 : existing.pipeline;
                        if (this.config.debugLogging) {
                            this.logPipelineDebug(payload, pipelineValue, Array.isArray(existing === null || existing === void 0 ? void 0 : existing.pipeline) ? existing.pipeline : undefined);
                        }
                        optionsValue = (_d = payload.options) !== null && _d !== void 0 ? _d : existing === null || existing === void 0 ? void 0 : existing.options;
                        explainPlanValue = typeof payload.explainPlan !== 'undefined' ? payload.explainPlan : existing === null || existing === void 0 ? void 0 : existing.explain_plan;
                        explainStatsValue = typeof payload.explainExecutionStats !== 'undefined' ? payload.explainExecutionStats : existing === null || existing === void 0 ? void 0 : existing.explain_execution_stats;
                        explainGeneratedAtValue = typeof payload.explainGeneratedAt !== 'undefined'
                            ? this.coerceDate(payload.explainGeneratedAt)
                            : existing === null || existing === void 0 ? void 0 : existing.explain_generated_at;
                        fingerprintScopeKey = this.buildFingerprintScopeKey({
                            clientSlug: (_e = payload.clientSlug) !== null && _e !== void 0 ? _e : existing === null || existing === void 0 ? void 0 : existing.client_slug,
                            clientName: (_f = payload.clientName) !== null && _f !== void 0 ? _f : existing === null || existing === void 0 ? void 0 : existing.client_name,
                            sourceApp: (_g = payload.sourceApp) !== null && _g !== void 0 ? _g : existing === null || existing === void 0 ? void 0 : existing.source_app,
                            environment: (_h = payload.environment) !== null && _h !== void 0 ? _h : existing === null || existing === void 0 ? void 0 : existing.environment,
                            publication: (_j = payload.publication) !== null && _j !== void 0 ? _j : existing === null || existing === void 0 ? void 0 : existing.publication,
                            serverUrl: (_k = payload.server_url) !== null && _k !== void 0 ? _k : existing === null || existing === void 0 ? void 0 : existing.server_url
                        });
                        canonicalFingerprint = this.buildCanonicalFingerprint(payload.collection, filterValue, pipelineValue, optionsValue);
                        setFields = {
                            query_hash: payload.queryHash,
                            collection: payload.collection,
                            canonical_fingerprint: canonicalFingerprint.serialized,
                            canonical_fingerprint_hash: canonicalFingerprint.hash,
                            fingerprint_scope_key: fingerprintScopeKey,
                            filter: filterValue,
                            pipeline: pipelineValue,
                            options: optionsValue,
                            duration_ms: payload.durationMs,
                            max_duration_ms: maxDuration,
                            avg_duration_ms: avgDuration,
                            threshold_ms: typeof payload.thresholdMs === 'number' ? payload.thresholdMs : existing === null || existing === void 0 ? void 0 : existing.threshold_ms,
                            explain_plan: explainPlanValue,
                            explain_execution_stats: explainStatsValue,
                            explain_generated_at: explainGeneratedAtValue,
                            client_slug: (_l = payload.clientSlug) !== null && _l !== void 0 ? _l : existing === null || existing === void 0 ? void 0 : existing.client_slug,
                            client_name: (_m = payload.clientName) !== null && _m !== void 0 ? _m : existing === null || existing === void 0 ? void 0 : existing.client_name,
                            environment: (_o = payload.environment) !== null && _o !== void 0 ? _o : existing === null || existing === void 0 ? void 0 : existing.environment,
                            source_app: (_p = payload.sourceApp) !== null && _p !== void 0 ? _p : existing === null || existing === void 0 ? void 0 : existing.source_app,
                            node_hostname: (_q = payload.nodeHostname) !== null && _q !== void 0 ? _q : existing === null || existing === void 0 ? void 0 : existing.node_hostname,
                            server_url: (_r = payload.server_url) !== null && _r !== void 0 ? _r : existing === null || existing === void 0 ? void 0 : existing.server_url,
                            occurrences: occurrences,
                            last_seen_at: now,
                            status: resolvedStatus,
                            ignored: resolvedIgnored,
                            notes: typeof payload.notes === 'string' ? payload.notes : existing === null || existing === void 0 ? void 0 : existing.notes,
                            publication: (_s = payload.publication) !== null && _s !== void 0 ? _s : existing === null || existing === void 0 ? void 0 : existing.publication,
                            subscription_data: (_t = payload.subscription_data) !== null && _t !== void 0 ? _t : existing === null || existing === void 0 ? void 0 : existing.subscription_data,
                            user_id: (_u = payload.userId) !== null && _u !== void 0 ? _u : existing === null || existing === void 0 ? void 0 : existing.user_id
                        };
                        cleaned = this.cleanSet(setFields);
                        if (!existing) return [3 /*break*/, 6];
                        cleaned.updatedAt = now;
                        return [4 /*yield*/, SlowQueryLogs.updateOne({ _id: existing._id }, { $set: cleaned })];
                    case 4:
                        _v.sent();
                        return [4 /*yield*/, SlowQueryLogs.findOne({ _id: existing._id })];
                    case 5: return [2 /*return*/, _v.sent()];
                    case 6:
                        doc = __assign(__assign({ _id: (0, common_1.objectIdHexString)() }, cleaned), { slow_query_count: 0, slow_query_count_string: 'Pending', auto_fix_attempt_count: 0, first_seen_at: now, createdAt: now, updatedAt: now, verification_status: 'pending', verification_runs: [], verification_next_run_at: now });
                        return [4 /*yield*/, SlowQueryLogs.insertOne(doc)];
                    case 7:
                        _v.sent();
                        return [4 /*yield*/, SlowQueryLogs.findOne({ _id: doc._id })];
                    case 8: return [2 /*return*/, _v.sent()];
                }
            });
        });
    };
    SlowQueryManager.prototype.buildLegacyDedupeQuery = function (payload) {
        var dedupeQuery = {
            query_hash: payload.queryHash,
            collection: payload.collection
        };
        if (payload.clientSlug) {
            dedupeQuery.client_slug = payload.clientSlug;
        }
        if (payload.environment) {
            dedupeQuery.environment = payload.environment;
        }
        if (payload.sourceApp) {
            dedupeQuery.source_app = payload.sourceApp;
        }
        if (payload.publication) {
            dedupeQuery.publication = payload.publication;
        }
        if (payload.server_url) {
            dedupeQuery.server_url = payload.server_url;
        }
        return dedupeQuery;
    };
    SlowQueryManager.prototype.buildFingerprintScopeKey = function (scope) {
        var clientKey = this.normalizeScopeSegment(scope.clientSlug || scope.clientName || '');
        var sourceApp = this.normalizeScopeSegment(scope.sourceApp || '');
        var environment = this.normalizeScopeSegment(scope.environment || '');
        var publication = this.normalizeScopeSegment(scope.publication || '');
        var serverUrl = this.normalizeScopeSegment(scope.serverUrl || '');
        return [clientKey, sourceApp, environment, publication, serverUrl].join('|');
    };
    SlowQueryManager.prototype.normalizeScopeSegment = function (value) {
        var normalized = String(value || '')
            .trim()
            .toLowerCase()
            .replace(/\s+/g, ' ');
        return normalized || '_';
    };
    SlowQueryManager.prototype.buildCanonicalFingerprint = function (collection, filterValue, pipelineValue, optionsValue) {
        var canonicalPayload = {
            collection: this.normalizeScopeSegment(collection),
            filter: this.normalizeCanonicalValue(filterValue, 'filter'),
            pipeline: this.normalizeCanonicalValue(Array.isArray(pipelineValue) ? pipelineValue : [], 'pipeline'),
            options: this.normalizeCanonicalValue(optionsValue !== null && optionsValue !== void 0 ? optionsValue : {}, 'options')
        };
        var serialized = JSON.stringify(canonicalPayload);
        var hash = (0, crypto_1.createHash)('sha256').update(serialized, 'utf8').digest('hex');
        return { serialized: serialized, hash: hash };
    };
    SlowQueryManager.prototype.normalizeCanonicalValue = function (value, parentKey) {
        var _this = this;
        if (parentKey === void 0) { parentKey = ''; }
        if (value === null || typeof value === 'undefined') {
            return null;
        }
        if (value instanceof Date) {
            return '__date__';
        }
        if (value instanceof RegExp) {
            return '__regex__';
        }
        if (Buffer.isBuffer(value)) {
            return '__binary__';
        }
        var valueType = typeof value;
        if (valueType === 'string') {
            return this.normalizeCanonicalString(value, parentKey);
        }
        if (valueType === 'number') {
            return '__num__';
        }
        if (valueType === 'boolean') {
            return value;
        }
        if (valueType === 'bigint') {
            return '__num__';
        }
        if (valueType === 'function') {
            return '__fn__';
        }
        if (Array.isArray(value)) {
            var normalizedItems = value.map(function (entry) { return _this.normalizeCanonicalValue(entry, parentKey); });
            if (['$and', '$or', '$in', '$nin', '$all'].includes(parentKey)) {
                var sortable = normalizedItems.map(function (item) { return ({
                    item: item,
                    serialized: JSON.stringify(item)
                }); });
                sortable.sort(function (left, right) { return left.serialized.localeCompare(right.serialized); });
                return sortable.map(function (entry) { return entry.item; });
            }
            return normalizedItems;
        }
        if (valueType === 'object') {
            if (this.isObjectIdLikeValue(value)) {
                return '__objectid__';
            }
            var normalizedObj_1 = {};
            Object.keys(value).sort().forEach(function (key) {
                normalizedObj_1[key] = _this.normalizeCanonicalValue(value[key], key);
            });
            return normalizedObj_1;
        }
        return '__literal__';
    };
    SlowQueryManager.prototype.normalizeCanonicalString = function (value, parentKey) {
        if (parentKey === void 0) { parentKey = ''; }
        var trimmed = String(value || '').trim();
        if (!trimmed) {
            return '__empty__';
        }
        if (parentKey === '$regex') {
            return '__regex__';
        }
        if (DATE_HINT_KEY_PATTERN.test(parentKey) || ISO_DATE_PATTERN.test(trimmed)) {
            return '__date__';
        }
        if (OBJECT_ID_PATTERN.test(trimmed)) {
            return '__objectid__';
        }
        if (UUID_PATTERN.test(trimmed)) {
            return '__uuid__';
        }
        if (NUMERIC_STRING_PATTERN.test(trimmed)) {
            return trimmed.length >= 10 ? '__numstr_large__' : '__numstr__';
        }
        if (ID_HINT_KEY_PATTERN.test(parentKey) || TOKEN_LIKE_PATTERN.test(trimmed)) {
            return '__token__';
        }
        return '__str__';
    };
    SlowQueryManager.prototype.isObjectIdLikeValue = function (value) {
        if (!value || typeof value !== 'object') {
            return false;
        }
        var bsonType = String(value._bsontype || '').trim().toLowerCase();
        if (bsonType === 'objectid') {
            return true;
        }
        if (typeof value.toHexString === 'function') {
            var hexValue = String(value.toHexString() || '').trim();
            return OBJECT_ID_PATTERN.test(hexValue);
        }
        return false;
    };
    SlowQueryManager.prototype.resolveConfig = function () {
        var slowQueryConfig = (this.serverConfig && (this.serverConfig.slowQuery || this.serverConfig.SLOW_QUERY)) || {};
        var getBoolean = function (envKey, configKey, fallback) {
            if (fallback === void 0) { fallback = true; }
            if (typeof process.env[envKey] !== 'undefined') {
                return process.env[envKey] === 'true';
            }
            if (typeof slowQueryConfig[configKey] !== 'undefined') {
                return !!slowQueryConfig[configKey];
            }
            return fallback;
        };
        var parseKeyList = function (value) {
            if (Array.isArray(value)) {
                return value.map(function (item) { return "".concat(item || '').trim(); }).filter(Boolean);
            }
            if (typeof value === 'string') {
                return value.split(',').map(function (item) { return item.trim(); }).filter(Boolean);
            }
            return [];
        };
        var ingestSource = typeof process.env.SLOW_QUERY_INGEST_KEYS !== 'undefined'
            ? process.env.SLOW_QUERY_INGEST_KEYS
            : slowQueryConfig.ingestKeys;
        return {
            enabled: getBoolean('SLOW_QUERY_ENABLED', 'enabled', true),
            ingestKeys: parseKeyList(ingestSource),
            debugLogging: getBoolean('SLOW_QUERY_DEBUG_LOGS', 'debugLogging', false),
            configSource: process.env.SLOW_QUERY_ENABLED ? 'environment' : (Object.keys(slowQueryConfig).length ? 'serverConfig' : 'defaults')
        };
    };
    SlowQueryManager.prototype.cleanSet = function (input) {
        var output = {};
        Object.keys(input).forEach(function (key) {
            if (typeof input[key] !== 'undefined') {
                output[key] = input[key];
            }
        });
        return output;
    };
    SlowQueryManager.prototype.coerceDate = function (value) {
        if (!value) {
            return undefined;
        }
        if (value instanceof Date && !Number.isNaN(value.getTime())) {
            return value;
        }
        var parsed = new Date(value);
        return Number.isNaN(parsed.getTime()) ? undefined : parsed;
    };
    SlowQueryManager.prototype.logPipelineDebug = function (payload, pipelineValue, existingPipeline) {
        if (!this.config.debugLogging) {
            return;
        }
        var source = Array.isArray(payload.pipeline)
            ? 'payload'
            : (Array.isArray(existingPipeline) ? 'existing' : 'none');
        var length = Array.isArray(pipelineValue) ? pipelineValue.length : 0;
        var stages = this.describePipelineStages(pipelineValue);
        console.info("[SlowQueryManager][pipeline] collection=".concat(payload.collection, " queryHash=").concat(payload.queryHash, " source=").concat(source, " len=").concat(length, " stages=").concat(stages));
    };
    SlowQueryManager.prototype.describePipelineStages = function (pipeline) {
        if (!Array.isArray(pipeline) || pipeline.length === 0) {
            return 'empty';
        }
        var snippet = pipeline.slice(0, 3).map(function (stage) {
            if (!stage || typeof stage !== 'object') {
                return 'unknown';
            }
            var key = Object.keys(stage)[0];
            return key ? key : 'stage';
        });
        var additional = pipeline.length > snippet.length
            ? " (+".concat(pipeline.length - snippet.length, " more)")
            : '';
        return "".concat(snippet.join(', ')).concat(additional);
    };
    return SlowQueryManager;
}());
exports.SlowQueryManager = SlowQueryManager;
function ensureSlowQueryManager(serverConfig) {
    var existing = resolveio_server_app_1.ResolveIOServer['SlowQueryManager'];
    if (existing) {
        return existing;
    }
    if (!configuredSlowQueryManagerDependencies) {
        return null;
    }
    var resolvedServerConfig = serverConfig || resolveio_server_app_1.ResolveIOServer.getServerConfig();
    if (!resolvedServerConfig) {
        return null;
    }
    var manager = new SlowQueryManager(resolvedServerConfig);
    resolveio_server_app_1.ResolveIOServer['SlowQueryManager'] = manager;
    return manager;
}

//# sourceMappingURL=slow-query.manager.js.map
