bool BacklinkStoreDirty(bool set)
        {
            var res = Hash() != _settingIgnoredPathsHash1;

            if (set)
            {
                _settingIgnoredPathsHash1 = Hash();
            }
            return(res);

            int Hash()
            {
                var conf = Globals <Config> .Value;

                return(DirtyUtils.HashCode(conf.IgnorePathContainsCombined,
                                           conf.IgnoreMaterial,
                                           conf.IgnoreScriptable));
            }
        }
        bool VisualSettingDirty(bool set)
        {
            var res = Hash() != _settingCodeHash1;

            if (set)
            {
                _settingCodeHash1 = Hash();
            }
            return(res);

            int Hash()
            {
                var conf = Globals <Config> .Value;

                return(DirtyUtils.HashCode(
                           conf.MarkRed,
                           conf.ShowInfoBox,
                           conf.RebuildCacheOnDemand));
            }
        }
        void ShowTabMain(Config conf, WindowData windowData)
        {
            var store = Globals <BacklinkStore> .Value;

            EditorGUIUtility.labelWidth = windowData.Window.position.width * .7f;

            int Hash() => DirtyUtils.HashCode(conf.Locked);

            var active = SearchArgMain.Get1[0];

            if (conf.Locked && (windowData.FindFrom == FindModeEnum.File &&
                                (active == null || active.Main == null || !AssetDatabase.Contains(active.Main))))
            {
                conf.Locked = false;
                AufCtx.World.NewEntityWith(out RequestRepaintEvt _);
            }

            var style = windowData.Style;
            var hash  = Hash();

            if (hash != Hash())
            {
                PersistenceUtils.Save(in conf);
                AufCtx.World.NewEntityWith(out RequestRepaintEvt _);
            }

            // if (Globals<WindowData>.Get() == null) return;
            EditorGUILayout.Space();

            SearchArg arg = default;

            foreach (var i in SearchArgMain)
            {
                arg = SearchArgMain.Get1[i];
                if (arg != null && arg.Main != null)
                {
                    break;
                }
            }

            if (arg == default)
            {
                return;
            }

            var targetTypeEnum = GetTargetType(windowData, arg?.Main);

            BacklinkStore.UnusedQty unusedQty = new BacklinkStore.UnusedQty(0, 0, 0);

            using (new EditorGUILayout.HorizontalScope()) {
                var enabledBuf    = GUI.enabled;
                var selectedGuids = Selection.assetGUIDs;

                var undoRedoState = Globals <UndoRedoState> .Value;

                GUI.enabled = selectedGuids != null && !conf.Locked && undoRedoState.UndoEnabled;
                if (GUILayout.Button(style.ArrowL, style.ArrowBtn))
                {
                    AufCtx.World.NewEntityWith(out UndoEvt _);
                }

                GUI.enabled = selectedGuids != null && !conf.Locked && undoRedoState.RedoEnabled;
                if (GUILayout.Button(style.ArrowR, style.ArrowBtn))
                {
                    AufCtx.World.NewEntityWith(out RedoEvt _);
                }

                GUI.enabled = enabledBuf;

                if (conf.Locked)
                {
                    if (GUILayout.Button(style.Lock, style.LockBtn))
                    {
                        AufCtx.World.NewEntityWith(out SelectionChanged selectionChanged);
                        conf.Locked = false;
                        if (Selection.activeObject != arg.Target)
                        {
                            selectionChanged.From   = FindModeEnum.Scene;
                            selectionChanged.Scene  = SceneManager.GetActiveScene();
                            selectionChanged.Target = Selection.activeObject;
                        }
                        else if (Selection.assetGUIDs is string[] guids)
                        {
                            // todo show info box multiple selection is unsupported
                            if (guids.Length > 0)
                            {
                                var path = AssetDatabase.GUIDToAssetPath(guids[0]);
                                selectionChanged.Target = AssetDatabase.LoadAssetAtPath <Object>(path);
                                switch (Selection.selectionChanged.Target)
                                {
                                case DefaultAsset _:
                                    selectionChanged.From = FindModeEnum.File;
                                    break;

                                case GameObject go when go.scene.isLoaded:
                                    selectionChanged.From  = FindModeEnum.Scene;
                                    selectionChanged.Scene = SceneManager.GetActiveScene();
                                    break;

                                default:
                                    selectionChanged.From = FindModeEnum.File;
                                    break;
                                }
                            }
                            else if (Selection.activeObject is GameObject go && go.scene.isLoaded)
                            {
                                selectionChanged.From   = FindModeEnum.Scene;
                                selectionChanged.Target = Selection.activeObject;
                                selectionChanged.Scene  = SceneManager.GetActiveScene();
                            }
                        }
                    }
                }
                else
                {
                    var enabled = GUI.enabled;
                    GUI.enabled = selectedGuids != null && selectedGuids.Length == 1;
                    if (GUILayout.Button(style.Unlock, style.UnlockBtn))
                    {
                        conf.Locked = true;
                    }

                    GUI.enabled = enabled;
                }

                unusedQty = ShowObjectName(store, windowData, targetTypeEnum, arg, selectedGuids);
            }

            bool isMultiSelect = Selection.assetGUIDs != null && Selection.assetGUIDs.Length > 1;

            if (conf.ShowInfoBox)
            {
                if (isMultiSelect && (unusedQty.UnusedFilesQty + unusedQty.UnusedScenesQty > 0))
                {
                    var msgUnusedFiles = (unusedQty.UnusedFilesQty > 0)
                        ? $"unused files ({unusedQty.UnusedFilesQty}),"
                        : "";
                    var msgUnusedScenes = (unusedQty.UnusedScenesQty > 0)
                        ? $"unused scenes ({unusedQty.UnusedScenesQty}),"
                        : "";
                    var msgMultiSelect = $"This multi-selection contains: " +
                                         msgUnusedFiles + msgUnusedScenes +
                                         $"\nYou could delete them pressing corresponding button to the right.";
                    EditorGUILayout.HelpBox(msgMultiSelect, MessageType.Info);
                }
                else if (TryGetHelpInfo(arg, out var msg, out var msgType))
                {
                    EditorGUILayout.HelpBox(msg, msgType);
                }
            }

            if (targetTypeEnum != TargetTypeEnum.Directory && !isMultiSelect)
            {
                var windowData2 = Globals <WindowData> .Value;

                EditorGUILayout.BeginVertical();
                {
                    windowData2.ScrollPos = EditorGUILayout.BeginScrollView(windowData2.ScrollPos);
                    {
                        RenderRows(windowData2); //TODO?
                        EditorGUILayout.Space();
                    }
                    EditorGUILayout.EndScrollView();
                }
                EditorGUILayout.EndVertical();
                EditorGUILayout.Space();
            }
        }