/**
 * Третий уровень осознания (conscience_level_3).
 *
 * Алгоритм поиска действия по семантике и ЭП:
 *  — выборка getSemanticFramesForFinalImageId(актуальный стимул);
 *  — среди кадров семантики с приоритетом текущих (well, emotion) выбирается наиболее позитивный (max meanImportance);
 *  — выборка кадров ЭП: сначала perceptionNodeId + situationId, при отсутствии правила — только perceptionNodeId (situationId = 0);
 *  — из выборки — лучшее закрытое правило с effect > 0 и тем же stimulusImageId, что актуальный стимул;
 *  — при нахождении: info_automatismWithEpisodeFeedbackAndExpireCycle (ожидание кадра ЭП, цикл expired). Ответ —
 *    conscience_level_2 из episodic_memory.closeLastFrame; finalize — conscience_level_2_finalizeAutomatismAnswerCycle.
 *  — если такого правила нет: учительский fallback — info_teacherEpisodicRuleForAction по штатному ОД ветки;
 *    зеркала «Хочет играть»/«Хочет учить» (BasicMirrorActions 88, 89); при нахождении учительского кадра —
 *    AbstractImages_activateTeacherRuleOnAbstractions (клоны под актуальный стимул и ОД, правило в semanticStructure),
 *    затем info_automatismWithEpisodeFeedbackAndExpireCycle. У учительского кадра при поиске effect не ранжирует;
 *    мотор не запускается, если у кадра числовой effect ≤ 0 (согласование с осью «значимость»).
 *
 * Старт ур.3: при готовом ментальном автоматизме по умолчанию (ветка+ситуация), совпадающем с текущим кадром
 * semanticStructure (тот же ОД, что sourceActionImageId ментального образа) — сначала ментальный прогон
 * (MentalAutomatizms_run), затем запуск моторного автоматизма; дальнейший ур.3 не выполняется.
 * Иначе: при точном совпадении кадра в semanticStructure — автоматизм с ожиданием ЭП; далее семантика+ЭП,
 * затем учительский fallback.
 *
 * Вызов из канала ФО: conscience_level_3_runFromChannel(cycle).
 *
 * Устойчивость и согласованность значимости (реализовано в коде):
 *  — Пока цикл ждёт закрытия кадра ЭП после запуска автоматизма (`awaitingAutomatismEpisodeFeedback` без ответа
 *    оператора), повторный полный проход ур.3 не выполняется: иначе во втором/третьем вызове за тик канала
 *    срабатывала бы ветка «правило не найдено». Сообщения в лог цикла — через Consciousness_scheduler
 *    Consciousness_cycleAppendLog (часто с { force: true }: цикл после запуска автоматизма уже `expired`, иначе
 *    consciousness_dispatcher отбрасывает не-force записи).
 *  — Мотор по кадру semanticStructure (shortcut и ментальный путь): только «положительная значимость» кадра —
 *    учитель (`ruleKind === 'teacher'` или ненулевой ответ оператора на ОД), либо episodic с числовым effect > 0.
 *  — Путь семантика+ЭП: при meanImportance лучшего семантического кадра стимула < 0 мотор по найденному правилу
 *    ЭП не запускается (семантика стимула как демотиватор).
 *
 * Порядок попыток в conscience_level_3: ментальный автоматизм → shortcut semanticStructure → эпизодика → учитель.
 *
 * @param {Object} context
 * @param {Object} context.sourceCycle
 * @param {string} [context.reason]
 */
(function (global) {
  'use strict';

  /**
   * Узел «уже запущен автоматизм, ждём ЭП». Повторный вход в ур.3 в том же или следующем шаге не должен
   * снова искать правило и доходить до «правило не найдено» — отсюда ранний выход в conscience_level_3 и в
   * conscience_level_3_runFromChannel.runLevel3.
   */
  function conscience_level_3_shouldSkipBecauseAwaitingEpisodeFeedback(cycle) {
    return !!(cycle && cycle.awaitingAutomatismEpisodeFeedback && !cycle.automatismOperatorAnswerReceived);
  }

  /**
   * Единая проверка значимости кадра semanticStructure перед мотором (shortcut, ментальный путь).
   * Согласовано с abstract_images.js: teacher / ответ оператора на ОД трактуются как доверенный положительный
   * сигнал; episodic-слот без положительного числового effect не даёт права на мотор (нуль/отрицание/нет числа).
   * @param {Object|null} fr — кадр из AbstractImages_findRuleFrameMatchingContext
   */
  function conscience_level_3_semanticStructureFrameAllowsMotor(fr) {
    if (!fr) return false;
    if (fr.ruleKind === 'teacher') return true;
    var resp = fr.responseStimulusImageId != null ? parseInt(fr.responseStimulusImageId, 10) : 0;
    if (resp > 0) return true;
    var eff = fr.effect;
    if (typeof eff === 'number' && !isNaN(eff)) return eff > 0;
    return false;
  }

  function puls() {
    return typeof global.cpuls === 'number' ? global.cpuls : 0;
  }

  /**
   * Запись в debugLog цикла через consciousness_dispatcher.Consciousness_cycleAppendLog(cycle, text, puls, opts).
   * Без force: только главный цикл (как раньше в ФО). С force: запись и для фонового, и после expired цикла
   * (см. cycleAppendLog в dispatcher: expired && !opts.force → не пишем).
   */
  function appendCycleLog(cycle, text, force) {
    if (!cycle || typeof global.Consciousness_cycleAppendLog !== 'function') return;
    if (!force && !cycle.isMainCycle) return;
    global.Consciousness_cycleAppendLog(cycle, text, puls(), force ? { force: true } : undefined);
  }

  function reasonLabel(reason) {
    switch (reason) {
      case 'level2_survival_inaccurate_no_rush':
        return 'InaccurateRule без срочных виталов — отложенное планирование';
      case 'level2_survival_cry':
        return 'ветка «Плачет» / нет правил в ЭП';
      case 'dissatisfaction':
        return 'isDissatisfaction';
      default:
        return reason || '(без reason)';
    }
  }

  /**
   * Среди кадров SemanticObjectImportance для стимула: при наличии записей в текущем (well, emotion) — только они;
   * иначе весь массив. Возвращает объект с максимальным meanImportance.
   */
  function conscience_level_3_pickBestSemanticFrame(semFrames, well, emotionId) {
    if (!Array.isArray(semFrames) || !semFrames.length) return null;
    var narrowed = [];
    if (well && emotionId) {
      for (var i = 0; i < semFrames.length; i++) {
        var s = semFrames[i];
        if (s && s.wellNormaBad === well && s.emotionId === emotionId) narrowed.push(s);
      }
    }
    var pool = narrowed.length ? narrowed : semFrames;
    var best = null;
    var bestM = null;
    for (var j = 0; j < pool.length; j++) {
      var p = pool[j];
      if (!p) continue;
      var m = typeof p.meanImportance === 'number' && !isNaN(p.meanImportance) ? p.meanImportance : 0;
      if (best === null || m > bestM) {
        best = p;
        bestM = m;
      }
    }
    return best;
  }

  /**
   * Единая точка моторного запуска ур.3: создание/дефолт автоматизма + info_automatismWithEpisodeFeedbackAndExpireCycle.
   * До вызова сюда должны пройти все гейты значимости по выбранному пути (semanticStructure / ЭП / учитель).
   */
  function conscience_level_3_startAutomatismFromEpisodicRule(cycle, branchId, actionImageId) {
    if (!cycle || !branchId || !actionImageId) return false;
    var automatizmId = 0;
    if (typeof global.Automatizms_createAutomatizm === 'function') {
      automatizmId = global.Automatizms_createAutomatizm(branchId, actionImageId);
      if (automatizmId && typeof global.Automatizms_setDefaultAutomatizm === 'function') {
        global.Automatizms_setDefaultAutomatizm(automatizmId);
      }
    }
    if (typeof global.info_automatismWithEpisodeFeedbackAndExpireCycle === 'function') {
      return global.info_automatismWithEpisodeFeedbackAndExpireCycle(
        cycle,
        branchId,
        actionImageId,
        automatizmId,
        0,
        'Ур.3: автоматизм по правилу ЭП запущен, ожидание кадра ЭП.'
      );
    }
    if (typeof global.Consciousness_cycleAppendLog === 'function') {
      global.Consciousness_cycleAppendLog(cycle, 'Ур.3: info_automatismWithEpisodeFeedbackAndExpireCycle недоступна — мотор не запущен.', puls(), { force: true });
    }
    return false;
  }

  /**
   * @returns {boolean} true если автоматизм запущен
   */
  function conscience_level_3_trySemanticEpisodicAutomatism(cycle) {
    if (!cycle || cycle.status !== 'running') return false;
    if (cycle.awaitingAutomatismEpisodeFeedback && !cycle.automatismOperatorAnswerReceived) return false;

    var cx = cycle.context || {};
    var branchId = parseInt(cx.branchId, 10) || 0;
    var actualStim = parseInt(cx.actual_stimul_ID, 10) || 0;
    var info = typeof global.Info_initIfNeeded === 'function' ? global.Info_initIfNeeded() : global.InfoPicture;
    if (!actualStim && info && info.stimulus && info.stimulus.finalImageId) {
      actualStim = info.stimulus.finalImageId;
    }
    var situationId = info && typeof info.situationId === 'number' ? info.situationId : 0;
    var well = global.BadNormWell || 0;
    var emotionId = 0;
    if (typeof global.Emotions_getOrCreateEmotionId === 'function' && Array.isArray(global.BasicContextsActived)) {
      emotionId = global.Emotions_getOrCreateEmotionId(global.BasicContextsActived) || 0;
    }

    if (!branchId || !actualStim) {
      appendCycleLog(cycle, 'Ур.3: нет branchId или актуального стимула — пропуск поиска правила.');
      return false;
    }

    var semFrames = typeof global.getSemanticFramesForFinalImageId === 'function'
      ? global.getSemanticFramesForFinalImageId(actualStim) : [];
    if (!semFrames.length) {
      appendCycleLog(cycle, 'Ур.3: нет кадров семантики для FinalImageId=' + String(actualStim) + '.');
      return false;
    }

    var semBest = conscience_level_3_pickBestSemanticFrame(semFrames, well, emotionId);
    if (!semBest) {
      appendCycleLog(cycle, 'Ур.3: не удалось выбрать кадр семантики.');
      return false;
    }

    appendCycleLog(cycle, 'Ур.3: кадр семантики с max meanImportance=' + String(semBest.meanImportance) +
      ' (well=' + String(semBest.wellNormaBad) + ', emotionId=' + String(semBest.emotionId) + ').');

    if (typeof global.info_bestEpisodicRule !== 'function') {
      appendCycleLog(cycle, 'Ур.3: info_bestEpisodicRule недоступна.');
      return false;
    }

    var ruleBundle = global.info_bestEpisodicRule(branchId, situationId, {
      filterByStimulus: true,
      stimulusImageId: actualStim
    });
    var bestFrame = ruleBundle && ruleBundle.frame ? ruleBundle.frame : null;
    if (bestFrame) {
      appendCycleLog(cycle, 'Ур.3: правило ЭП для стимула ' + String(actualStim) + ', effect=' + String(bestFrame.effect) + ', ОД=' + String(bestFrame.actionImageId) + '.');
    }

    if (!bestFrame || !bestFrame.actionImageId) {
      appendCycleLog(cycle, 'Ур.3: нет закрытого правила с положительным effect для стимула ' + String(actualStim) + '.');
      return false;
    }

    // Значимость стимула в семантической памяти: отрицательная — демотиватор; не глушим эпизодический effect
    // положительным правилом, если контекст стимула уже «плохой» по усреднённой значимости.
    var semZ = typeof semBest.meanImportance === 'number' && !isNaN(semBest.meanImportance) ? semBest.meanImportance : null;
    if (semZ !== null && semZ < 0) {
      if (typeof global.Consciousness_cycleAppendLog === 'function') {
        global.Consciousness_cycleAppendLog(cycle, 'Ур.3: семантика стимула отрицательна (meanImportance=' + String(semZ) + ') — мотор по ЭП не запускаем.', puls(), { force: true });
      }
      return false;
    }

    return conscience_level_3_startAutomatismFromEpisodicRule(cycle, branchId, bestFrame.actionImageId);
  }

  /**
   * Учительское правило ЭП для штатного ОД ветки: при поиске effect не ранжирует; мотор блокируется, если в кадре
   * явно числовой effect ≤ 0. Зеркала 88, 89 — провокация режима обучения.
   * @returns {boolean}
   */
  function conscience_level_3_tryTeacherEpisodicAutomatism(cycle) {
    if (!cycle || cycle.status !== 'running') return false;
    if (cycle.awaitingAutomatismEpisodeFeedback && !cycle.automatismOperatorAnswerReceived) return false;

    var cx = cycle.context || {};
    var branchId = parseInt(cx.branchId, 10) || 0;
    if (!branchId) {
      appendCycleLog(cycle, 'Ур.3 (учитель): нет branchId.', true);
      return false;
    }

    var info = typeof global.Info_initIfNeeded === 'function' ? global.Info_initIfNeeded() : global.InfoPicture;
    var situationId = info && typeof info.situationId === 'number' ? info.situationId : 0;
    var actualStim = parseInt(cx.actual_stimul_ID, 10) || 0;
    if (!actualStim && info && info.stimulus && info.stimulus.finalImageId) {
      actualStim = info.stimulus.finalImageId;
    }

    var def = typeof global.Automatizms_getDefaultAutomatizmForBranch === 'function'
      ? global.Automatizms_getDefaultAutomatizmForBranch(branchId)
      : null;
    var odId = def && def.actionsImageId != null ? parseInt(def.actionsImageId, 10) : 0;
    if (!odId) {
      appendCycleLog(cycle, 'Ур.3 (учитель): у ветки нет штатного ОД — поиск учительского правила пропущен.', true);
      return false;
    }

    var bundle = typeof global.info_teacherEpisodicRuleForAction === 'function'
      ? global.info_teacherEpisodicRuleForAction(branchId, situationId, odId)
      : null;

    if (typeof global.activateStimulusForBasicMirrorActionId === 'function') {
      global.activateStimulusForBasicMirrorActionId(88);
      global.activateStimulusForBasicMirrorActionId(89);
    }

    if (!bundle || !bundle.frame || !bundle.frame.actionImageId) {
      appendCycleLog(cycle, 'Ур.3 (учитель): в ЭП нет кадра с ответом оператора на ОД ' + String(odId) + '.', true);
      return false;
    }

    var tEff = bundle.frame.effect;
    if (typeof tEff === 'number' && !isNaN(tEff) && tEff <= 0) {
      if (typeof global.Consciousness_cycleAppendLog === 'function') {
        global.Consciousness_cycleAppendLog(cycle, 'Ур.3 (учитель): кадр ЭП с effect ≤ 0 — запуск автоматизма пропущен.', puls(), { force: true });
      }
      return false;
    }

    if (actualStim && typeof global.AbstractImages_activateTeacherRuleOnAbstractions === 'function') {
      var ar = global.AbstractImages_activateTeacherRuleOnAbstractions({
        perceptionNodeId: branchId,
        situationId: situationId,
        actualStimulusImageId: actualStim,
        teacherEpisodicFrame: bundle.frame
      });
      if (ar && (ar.abstractPerceptionId || ar.abstractActionId)) {
        appendCycleLog(cycle, 'Ур.3 (учитель): абстракции #' + String(ar.abstractPerceptionId || 0) + ' (воспр.) / #' +
          String(ar.abstractActionId || 0) + ' (действ.) — слот учителя в semanticStructure.', true);
      }
    } else {
      appendCycleLog(cycle, 'Ур.3 (учитель): нет актуального FinalImageId — абстракции и semanticStructure не трогаем.', true);
    }

    appendCycleLog(cycle, 'Ур.3 (учитель): ' + (bundle.exactRule ? 'полное условие (ветка+ситуация)' : 'только ветка') +
      ', ОД=' + String(bundle.frame.actionImageId) + ', ответ оператора FinalImageId=' +
      String(bundle.frame.responseStimulusImageId) + ' — запуск автоматизма.', true);

    return conscience_level_3_startAutomatismFromEpisodicRule(cycle, branchId, bundle.frame.actionImageId);
  }

  /**
   * Готовый ментальный автоматизм: кадр semanticStructure совпадает с sourceActionImageId МАИ;
   * мотор — только при положительной значимости кадра (см. conscience_level_3_semanticStructureFrameAllowsMotor).
   * @returns {boolean}
   */
  function conscience_level_3_tryReadyMentalAutomatismThenMotor(cycle) {
    if (!cycle || cycle.status !== 'running') return false;
    if (cycle.awaitingAutomatismEpisodeFeedback && !cycle.automatismOperatorAnswerReceived) return false;

    var cx = cycle.context || {};
    var branchId = parseInt(cx.branchId, 10) || 0;
    var actualStim = parseInt(cx.actual_stimul_ID, 10) || 0;
    var info = typeof global.Info_initIfNeeded === 'function' ? global.Info_initIfNeeded() : global.InfoPicture;
    if (!actualStim && info && info.stimulus && info.stimulus.finalImageId) {
      actualStim = info.stimulus.finalImageId;
    }
    var situationId = info && typeof info.situationId === 'number' ? info.situationId : 0;

    if (!branchId || !actualStim) return false;
    if (typeof global.MentalAutomatizms_getDefaultForThemeSituation !== 'function') return false;
    if (typeof global.AbstractImages_findRuleFrameMatchingContext !== 'function') return false;

    var fr = global.AbstractImages_findRuleFrameMatchingContext({
      perceptionNodeId: branchId,
      situationId: situationId,
      actualStimulusImageId: actualStim
    });
    if (!fr || fr.actionImageId == null) return false;
    var frameOd = parseInt(fr.actionImageId, 10) || 0;
    if (!frameOd) return false;

    var ma = global.MentalAutomatizms_getDefaultForThemeSituation(branchId, situationId);
    if (!ma || !ma.mentalActionImageId) return false;

    if (typeof global.MentalActionImages_get !== 'function') return false;
    var mai = global.MentalActionImages_get(ma.mentalActionImageId);
    if (!mai) return false;
    var srcOd = parseInt(mai.sourceActionImageId, 10) || 0;
    if (!srcOd || srcOd !== frameOd) return false;

    if (!conscience_level_3_semanticStructureFrameAllowsMotor(fr)) {
      if (typeof global.Consciousness_cycleAppendLog === 'function') {
        global.Consciousness_cycleAppendLog(cycle, 'Ур.3: ментальный автоматизм — кадр semanticStructure без положительной значимости, мотор не запускаем.', puls(), { force: true });
      }
      return false;
    }

    if (typeof global.Consciousness_cycleAppendLog === 'function') {
      global.Consciousness_cycleAppendLog(cycle, 'Ур.3: готовый ментальный автоматизм #' + String(ma.id) + ' (МАИ #' +
        String(ma.mentalActionImageId) + ') → моторный ОД ' + String(srcOd) + '.', puls(), { force: true });
    }

    if (typeof global.MentalAutomatizms_run === 'function') {
      global.MentalAutomatizms_run(ma.id);
    }

    return conscience_level_3_startAutomatismFromEpisodicRule(cycle, branchId, srcOd);
  }

  /**
   * Правило в semanticStructure клона восприятия под ветку/ситуацию/стимул; мотор при положительной значимости кадра.
   * @returns {boolean}
   */
  function conscience_level_3_tryAbstractSemanticStructureShortcut(cycle) {
    if (!cycle || cycle.status !== 'running') return false;
    if (cycle.awaitingAutomatismEpisodeFeedback && !cycle.automatismOperatorAnswerReceived) return false;

    var cx = cycle.context || {};
    var branchId = parseInt(cx.branchId, 10) || 0;
    var actualStim = parseInt(cx.actual_stimul_ID, 10) || 0;
    var info = typeof global.Info_initIfNeeded === 'function' ? global.Info_initIfNeeded() : global.InfoPicture;
    if (!actualStim && info && info.stimulus && info.stimulus.finalImageId) {
      actualStim = info.stimulus.finalImageId;
    }
    var situationId = info && typeof info.situationId === 'number' ? info.situationId : 0;

    if (!branchId || !actualStim) return false;
    if (typeof global.AbstractImages_findRuleFrameMatchingContext !== 'function') return false;

    var fr = global.AbstractImages_findRuleFrameMatchingContext({
      perceptionNodeId: branchId,
      situationId: situationId,
      actualStimulusImageId: actualStim
    });
    if (!fr || fr.actionImageId == null) return false;

    var aid = parseInt(fr.actionImageId, 10) || 0;
    if (!aid) return false;

    if (!conscience_level_3_semanticStructureFrameAllowsMotor(fr)) {
      if (typeof global.Consciousness_cycleAppendLog === 'function') {
        global.Consciousness_cycleAppendLog(cycle, 'Ур.3: semanticStructure есть, но значимость кадра не положительная — shortcut к мотору пропущен.', puls(), { force: true });
      }
      return false;
    }

    if (typeof global.Consciousness_cycleAppendLog === 'function') {
      global.Consciousness_cycleAppendLog(cycle, 'Ур.3: semanticStructure восприятия — точное совпадение (ruleKind=' + String(fr.ruleKind || '') +
        '), ОД=' + String(aid) + '.', puls(), { force: true });
    }

    return conscience_level_3_startAutomatismFromEpisodicRule(cycle, branchId, aid);
  }

  function conscience_level_3(context) {
    var cycle = context && context.sourceCycle;
    var reason = (context && context.reason) || '';
    if (!cycle) return;

    if (conscience_level_3_shouldSkipBecauseAwaitingEpisodeFeedback(cycle)) {
      if (typeof global.Consciousness_cycleAppendLog === 'function') {
        global.Consciousness_cycleAppendLog(cycle, 'Ур.3: полный пайплайн не выполняется — ожидание кадра ЭП по ранее запущенному автоматизму.', puls(), { force: true });
      }
      return;
    }

    if (typeof global.Consciousness_cycleAppendLog === 'function' && cycle.isMainCycle) {
      var msg;
      switch (reason) {
        case 'level2_survival_inaccurate_no_rush':
          msg = 'Ур.3: вызов после ур.2 (InaccurateRule без срочных виталов).';
          break;
        case 'level2_survival_cry':
          msg = 'Ур.3: вызов после ур.2 (ветка «Плачет» / нет правил в ЭП).';
          break;
        case 'dissatisfaction':
          msg = 'Триггер isDissatisfaction: открывается 3-й уровень осознания.';
          break;
        default:
          msg = 'Ур.3: ' + reasonLabel(reason) + '.';
      }
      global.Consciousness_cycleAppendLog(cycle, msg, puls());
    }

    if (conscience_level_3_tryReadyMentalAutomatismThenMotor(cycle)) {
      return;
    }

    if (conscience_level_3_tryAbstractSemanticStructureShortcut(cycle)) {
      return;
    }

    if (conscience_level_3_trySemanticEpisodicAutomatism(cycle)) {
      return;
    }

    if (conscience_level_3_tryTeacherEpisodicAutomatism(cycle)) {
      return;
    }

    // Ни один путь не дал мотор; цикл остаётся без нового автоматизма — дальше заготовка планирования ур.3.
    if (typeof global.Consciousness_cycleAppendLog === 'function') {
      global.Consciousness_cycleAppendLog(cycle, 'Ур.3: правило не найдено — продолжение (заготовка).', puls(), { force: true });
    }
  }

  function conscience_level_3_runFromChannel(cycle) {
    if (!cycle || cycle.status !== 'running') return;

    /**
     * Гештальт (ур.4): до пайплайна ур.3 выставляется global.GestaltContextForLevel3 — образ цели и status
     * открытой доминанты (если есть). Не меняет ветвление ур.3.
     */
    if (typeof global.Gestalt_prepareContextForCycle === 'function') {
      try {
        global.Gestalt_prepareContextForCycle(cycle);
      } catch (eGestaltPrep) {}
    }

    /**
     * Один вызов conscience_level_3 за причину; если предыдущая причина в том же тике уже запустила автоматизм,
     * не входим в пайплайн повторно и фиксируем это в логе цикла (Consciousness_cycleAppendLog с force).
     */
    function runLevel3(reason) {
      if (!cycle || cycle.status !== 'running') return;
      if (conscience_level_3_shouldSkipBecauseAwaitingEpisodeFeedback(cycle)) {
        if (typeof global.Consciousness_cycleAppendLog === 'function') {
          global.Consciousness_cycleAppendLog(cycle, 'Ур.3: повторный вход пропущен (reason=' + String(reason) + ') — уже ожидание кадра ЭП по автоматизму.', puls(), { force: true });
        }
        return;
      }
      conscience_level_3({ sourceCycle: cycle, reason: reason });
    }

    if (cycle.survivalDeferredLevel3Planning) {
      runLevel3('level2_survival_inaccurate_no_rush');
      cycle.survivalDeferredLevel3Planning = false;
    }

    if (cycle.survivalCryLevel3Pending) {
      runLevel3('level2_survival_cry');
      cycle.survivalCryLevel3Pending = false;
    }

    if (global.InfoPicture && global.InfoPicture.isDissatisfaction) {
      runLevel3('dissatisfaction');
    }
  }

  global.conscience_level_3 = conscience_level_3;
  global.conscience_level_3_runFromChannel = conscience_level_3_runFromChannel;
})(window);
