Full Code of MiniZinc/MiniZincIDE for AI

master b6fea3f06081 cached
267 files
1.2 MB
312.4k tokens
1067 symbols
1 requests
Download .txt
Showing preview only (1,282K chars total). Download the full file or copy to clipboard to get everything.
Repository: MiniZinc/MiniZincIDE
Branch: master
Commit: b6fea3f06081
Files: 267
Total size: 1.2 MB

Directory structure:
gitextract_jgwfs6f5/

├── .envrc
├── .gitignore
├── .gitlab-ci.yml
├── LICENSE.txt
├── MiniZincIDE/
│   ├── CHANGES
│   ├── MiniZincIDE.pri
│   ├── MiniZincIDE.pro
│   ├── README.txt
│   ├── cheat_sheet.mzn
│   ├── checkupdatedialog.cpp
│   ├── checkupdatedialog.h
│   ├── checkupdatedialog.ui
│   ├── codechecker.cpp
│   ├── codechecker.h
│   ├── codeeditor.cpp
│   ├── codeeditor.h
│   ├── configwindow.cpp
│   ├── configwindow.h
│   ├── configwindow.ui
│   ├── dark_mode.css
│   ├── darkmodenotifier.cpp
│   ├── darkmodenotifier.h
│   ├── darkmodenotifier_macos.mm
│   ├── elapsedtimer.cpp
│   ├── elapsedtimer.h
│   ├── esclineedit.cpp
│   ├── esclineedit.h
│   ├── exception.h
│   ├── extraparamdialog.cpp
│   ├── extraparamdialog.h
│   ├── extraparamdialog.ui
│   ├── fzndoc.cpp
│   ├── fzndoc.h
│   ├── gotolinedialog.cpp
│   ├── gotolinedialog.h
│   ├── gotolinedialog.ui
│   ├── highlighter.cpp
│   ├── highlighter.h
│   ├── history.cpp
│   ├── history.h
│   ├── ide.cpp
│   ├── ide.h
│   ├── ideutils.cpp
│   ├── ideutils.h
│   ├── images/
│   │   └── about.html
│   ├── main.cpp
│   ├── mainwindow.cpp
│   ├── mainwindow.h
│   ├── mainwindow.ui
│   ├── minizincide.qrc
│   ├── moocsubmission.cpp
│   ├── moocsubmission.h
│   ├── moocsubmission.ui
│   ├── mznide-makefile.plist
│   ├── mznide-xcode.plist
│   ├── mznide.icns
│   ├── outputdockwidget.cpp
│   ├── outputdockwidget.h
│   ├── outputwidget.cpp
│   ├── outputwidget.h
│   ├── outputwidget.ui
│   ├── paramdialog.cpp
│   ├── paramdialog.h
│   ├── paramdialog.ui
│   ├── preferencesdialog.cpp
│   ├── preferencesdialog.h
│   ├── preferencesdialog.ui
│   ├── process.cpp
│   ├── process.h
│   ├── profilecompilation.cpp
│   ├── profilecompilation.h
│   ├── project.cpp
│   ├── project.h
│   ├── projectbrowser.cpp
│   ├── projectbrowser.h
│   ├── projectbrowser.ui
│   ├── server/
│   │   ├── connector.js
│   │   └── index.html
│   ├── server.cpp
│   ├── server.h
│   ├── solver.cpp
│   ├── solver.h
│   ├── theme.cpp
│   └── theme.h
├── MiniZincIDE.pro
├── README.md
├── TODO.txt
├── cp-profiler/
│   ├── README.md
│   ├── cp-profiler.pri
│   ├── cp-profiler.pro
│   └── src/
│       ├── cpp-integration/
│       │   ├── README.md
│       │   ├── connector.hpp
│       │   └── message.hpp
│       ├── cpprofiler/
│       │   ├── analysis/
│       │   │   ├── histogram_scene.cpp
│       │   │   ├── histogram_scene.hh
│       │   │   ├── merge_window.cpp
│       │   │   ├── merge_window.hh
│       │   │   ├── merging/
│       │   │   │   ├── merge_result.hh
│       │   │   │   ├── pentagon_list_widget.hh
│       │   │   │   ├── pentagon_rect.cpp
│       │   │   │   └── pentagon_rect.hh
│       │   │   ├── nogood_analysis_dialog.hh
│       │   │   ├── path_comp.cpp
│       │   │   ├── path_comp.hh
│       │   │   ├── pattern_rect.cpp
│       │   │   ├── pattern_rect.hh
│       │   │   ├── pentagon_counter.hpp
│       │   │   ├── similar_subtree_analysis.cpp
│       │   │   ├── similar_subtree_analysis.hh
│       │   │   ├── similar_subtree_window.cpp
│       │   │   ├── similar_subtree_window.hh
│       │   │   ├── subtree_pattern.hh
│       │   │   ├── tree_merger.cpp
│       │   │   └── tree_merger.hh
│       │   ├── command_line_parser.cpp
│       │   ├── command_line_parser.hh
│       │   ├── conductor.cpp
│       │   ├── conductor.hh
│       │   ├── config.hh
│       │   ├── core.cpp
│       │   ├── core.hh
│       │   ├── db_handler.cpp
│       │   ├── db_handler.hh
│       │   ├── execution.cpp
│       │   ├── execution.hh
│       │   ├── execution_list.cpp
│       │   ├── execution_list.hh
│       │   ├── execution_window.cpp
│       │   ├── execution_window.hh
│       │   ├── message_wrapper.hh
│       │   ├── name_map.cpp
│       │   ├── name_map.hh
│       │   ├── nogood_dialog.cpp
│       │   ├── nogood_dialog.hh
│       │   ├── options.hh
│       │   ├── pixel_views/
│       │   │   ├── icicle_canvas.cpp
│       │   │   ├── icicle_canvas.hh
│       │   │   ├── pixel_image.cpp
│       │   │   ├── pixel_image.hh
│       │   │   ├── pixel_item.hh
│       │   │   ├── pixel_widget.cpp
│       │   │   ├── pixel_widget.hh
│       │   │   ├── pt_canvas.cpp
│       │   │   └── pt_canvas.hh
│       │   ├── receiver_thread.cpp
│       │   ├── receiver_thread.hh
│       │   ├── receiver_worker.cpp
│       │   ├── receiver_worker.hh
│       │   ├── settings.hh
│       │   ├── solver_data.cpp
│       │   ├── solver_data.hh
│       │   ├── solver_id.hh
│       │   ├── stats_bar.hpp
│       │   ├── tcp_server.cpp
│       │   ├── tcp_server.hh
│       │   ├── tests/
│       │   │   ├── execution_test.cpp
│       │   │   ├── execution_test.hh
│       │   │   ├── tree_test.cpp
│       │   │   └── tree_test.hh
│       │   ├── tree/
│       │   │   ├── cursors/
│       │   │   │   ├── drawing_cursor.cpp
│       │   │   │   ├── drawing_cursor.hh
│       │   │   │   ├── hide_failed_cursor.cpp
│       │   │   │   ├── hide_failed_cursor.hh
│       │   │   │   ├── hide_not_highlighted_cursor.cpp
│       │   │   │   ├── hide_not_highlighted_cursor.hh
│       │   │   │   ├── layout_cursor.cpp
│       │   │   │   ├── layout_cursor.hh
│       │   │   │   ├── node_cursor.cpp
│       │   │   │   ├── node_cursor.hh
│       │   │   │   ├── nodevisitor.hh
│       │   │   │   └── nodevisitor.hpp
│       │   │   ├── layout.cpp
│       │   │   ├── layout.hh
│       │   │   ├── layout_computer.cpp
│       │   │   ├── layout_computer.hh
│       │   │   ├── node.cpp
│       │   │   ├── node.hh
│       │   │   ├── node_drawing.cpp
│       │   │   ├── node_drawing.hh
│       │   │   ├── node_id.cpp
│       │   │   ├── node_id.hh
│       │   │   ├── node_info.cpp
│       │   │   ├── node_info.hh
│       │   │   ├── node_stats.hh
│       │   │   ├── node_tree.cpp
│       │   │   ├── node_tree.hh
│       │   │   ├── node_widget.hh
│       │   │   ├── shape.cpp
│       │   │   ├── shape.hh
│       │   │   ├── structure.cpp
│       │   │   ├── structure.hh
│       │   │   ├── subtree_view.hh
│       │   │   ├── traditional_view.cpp
│       │   │   ├── traditional_view.hh
│       │   │   ├── tree_scroll_area.cpp
│       │   │   ├── tree_scroll_area.hh
│       │   │   ├── visual_flags.cpp
│       │   │   └── visual_flags.hh
│       │   ├── tree_builder.cpp
│       │   ├── tree_builder.hh
│       │   ├── user_data.cpp
│       │   ├── user_data.hh
│       │   └── utils/
│       │       ├── array.cpp
│       │       ├── array.hh
│       │       ├── debug.hh
│       │       ├── debug_mutex.hh
│       │       ├── maybe_caller.cpp
│       │       ├── maybe_caller.hh
│       │       ├── path_utils.cpp
│       │       ├── path_utils.hh
│       │       ├── perf_helper.cpp
│       │       ├── perf_helper.hh
│       │       ├── std_ext.cpp
│       │       ├── std_ext.hh
│       │       ├── string_utils.cpp
│       │       ├── string_utils.hh
│       │       ├── tree_utils.cpp
│       │       ├── tree_utils.hh
│       │       ├── utils.cpp
│       │       └── utils.hh
│       └── main_cpprofiler.cpp
├── default.nix
├── flake.nix
├── resources/
│   ├── README.md
│   ├── misc/
│   │   ├── COMBINED_LICENSE.txt
│   │   ├── MiniZincIDE.desktop
│   │   ├── README
│   │   ├── entitlements.xml
│   │   ├── minizinc.desktop
│   │   ├── osx-gecode-qt.conf
│   │   └── win-gecode-qt.conf
│   ├── pkg_config/
│   │   ├── Dockerfile
│   │   ├── minizinc-bundle.iss
│   │   └── snapcraft.yaml
│   └── scripts/
│       ├── AppRun
│       └── MiniZincIDE.sh
└── tests/
    ├── data/
    │   ├── mooc/
    │   │   ├── TestProject/
    │   │   │   ├── TestProject.mzp
    │   │   │   ├── _mooc
    │   │   │   ├── data/
    │   │   │   │   ├── n1.dzn
    │   │   │   │   └── n2.dzn
    │   │   │   └── models/
    │   │   │       ├── submission.mzc
    │   │   │       └── submission.mzn
    │   │   └── TestTerms/
    │   │       ├── TestTerms.mzp
    │   │       ├── _mooc
    │   │       ├── data/
    │   │       │   ├── n1.dzn
    │   │       │   └── n2.dzn
    │   │       └── models/
    │   │           ├── submission.mzc
    │   │           └── submission.mzn
    │   └── project/
    │       ├── configs/
    │       │   ├── solver1.mpc
    │       │   ├── solver2.mpc
    │       │   └── solver3.mpc
    │       ├── data/
    │       │   ├── data1.dzn
    │       │   └── data2.dzn
    │       ├── models/
    │       │   ├── model1.mzn
    │       │   └── model2.mzn
    │       ├── project-105-bad.mzp
    │       ├── project-105-good.mzp
    │       ├── project-106-bad.mzp
    │       └── project-106-good.mzp
    ├── testcpprofier.cpp
    ├── testdiff.cpp
    ├── testeditor.cpp
    ├── testide.cpp
    ├── testide.h
    ├── testmooc.cpp
    ├── testproject.cpp
    └── tests.pro

================================================
FILE CONTENTS
================================================

================================================
FILE: .envrc
================================================
use flake

================================================
FILE: .gitignore
================================================
*.pro.user
result


================================================
FILE: .gitlab-ci.yml
================================================
stages:
  - build
  - test
  - package
  - publish

default:
  interruptible: true

.cache:
  variables:
    CCACHE_DIR: "$CI_PROJECT_DIR/.ccache"
    CCACHE_MAXSIZE: "100M"
  cache:
    key: "$CI_JOB_STAGE:$CI_JOB_NAME"
    paths: [.ccache]

# ----------- Build MiniZincIDE -----------

build:linux:
  extends: .cache
  stage: build
  image: ghcr.io/minizinc/docker-build-environment:qt
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
    GIT_STRATEGY: clone
    DISABLE_COPYRIGHT_FILES_DEPLOYMENT: "1"
    DEBUG: "1"
  script:
    - mkdir -p build; cd build
    - qmake -makefile "CONFIG+=bundled" "CXX_PREFIX=ccache" "DEFINES+=MINIZINC_IDE_BUILD=\\\\\\\"\"${CI_PIPELINE_ID}\\\\\\\"\"" PREFIX=/usr ../MiniZincIDE/MiniZincIDE.pro
    - make -j4
    - make -j4 INSTALL_ROOT=../ide install; find ../ide/
    - cd ..
    # Download Gecode Gist so linuxdeploy can include its dependencies
    - sh ${VENDOR_SCRIPT} minizinc-vendor master gecode_gist:linux vendor.zip
    - unzip -q vendor.zip
    - linuxdeploy --appdir ide --executable vendor/gecode_gist/bin/fzn-gecode --plugin qt -v0
    - rm -rf ide/usr/share ide/usr/translations ide/usr/bin/fzn-gecode
  tags: [linux, docker]
  artifacts:
    paths: [ide/]

build:osx:
  extends: .cache
  stage: build
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
    GIT_STRATEGY: clone
  script:
    - mkdir -p build; cd build
    - qmake -makefile "CONFIG+=bundled" "CXX_PREFIX=ccache" "DEFINES+=MINIZINC_IDE_BUILD=\\\\\\\"\"${CI_PIPELINE_ID}\\\\\\\"\"" QMAKE_APPLE_DEVICE_ARCHS="x86_64 arm64" ../MiniZincIDE/MiniZincIDE.pro
    - make -j4
    - cp -r MiniZincIDE.app ..
  tags: [osx, cpp, qt]
  artifacts:
    paths: [MiniZincIDE.app]

build:win64:
  stage: build
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
    MZNARCH: "win64"
    BUILDCACHE_DIR: "$CI_PROJECT_DIR/.ccache"
    BUILDCACHE_MAX_CACHE_SIZE: "104857600"
  script:
    - if not exist "build" mkdir build
    - if not exist "ide" mkdir ide
    - cd build
    - qmake "CONFIG+=bundled" "CXX_PREFIX=buildcache" "DEFINES+=MINIZINC_IDE_BUILD=\\\\\\\"\"%CI_PIPELINE_ID%\\\\\\\"\"" ../MiniZincIDE/MiniZincIDE.pro
    - jom -j4
    - cp release/MiniZincIDE.exe ../ide
    - cd ../
    # Download Gecode Gist so windeployqt can include its dependencies
    - curl --silent -o vendor.zip --location --header "PRIVATE-TOKEN:%ACCESS_TOKEN%" "https://gitlab.com/api/v4/projects/minizinc%%2Fminizinc-vendor/jobs/artifacts/master/download?job=gecode_gist:%MZNARCH%"
    - unzip -q vendor.zip
    - cd ide
    - windeployqt --no-translations --no-compiler-runtime --no-system-d3d-compiler MiniZincIDE.exe ../vendor/gecode_gist/bin/fzn-gecode.exe
  tags: [win64, cpp, qt]
  artifacts:
    paths: [ide/]
  cache:
    key: "build_win64"
    paths: [.ccache]

# ----------- Test MiniZincIDE -----------

.tests_template:
  image: ghcr.io/minizinc/docker-build-environment:qt
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
    GIT_STRATEGY: clone
    QT_QPA_PLATFORM: offscreen
    MZN_SOLVER_PATH: ${CI_PROJECT_DIR}/vendor/gecode/share/minizinc/solvers/:${CI_PROJECT_DIR}/vendor/chuffed/share/minizinc/solvers
  before_script:
    - 'if [ -n "$CI_COMMIT_TAG" ]; then MZNREF="$CI_COMMIT_TAG"; elif [ "$CI_COMMIT_REF_NAME" = "master" ]; then MZNREF="master"; else MZNREF="develop"; fi'
    ### Download Dependencies
    - curl --silent -o minizinc.zip --location --header "PRIVATE-TOKEN:$ACCESS_TOKEN" "https://gitlab.com/api/v4/projects/minizinc%2Fminizinc/jobs/artifacts/$MZNREF/download?job=build:$MZNARCH"
    - unzip -q minizinc.zip
    - curl --silent -o vendor.zip --location --header "PRIVATE-TOKEN:$ACCESS_TOKEN" "https://gitlab.com/api/v4/projects/minizinc%2Fminizinc-vendor/jobs/artifacts/master/download?job=bundle:$MZNARCH"
    - unzip -q vendor.zip
    ### Add MiniZinc to path
    - export PATH=$CI_PROJECT_DIR/minizinc/bin:$PATH
  script:
    ### Build tests
    - mkdir -p test; cd test
    - qmake -makefile "CXX_PREFIX=ccache" ../tests/tests.pro
    - make -j4
    ### Run tests
    - make check
  needs: []

test:linux:
  extends: [.cache, .tests_template]
  variables:
    MZNARCH: linux
  tags: [linux, docker]

test:osx:
  extends: [.cache, .tests_template]
  variables:
    MZNARCH: osx
  tags: [osx, cpp, qt]

test:win64:
  extends: [.cache, .tests_template]
  variables:
    MZNARCH: win64
    MZN_SOLVER_PATH: ${CI_PROJECT_DIR}/vendor/gecode/share/minizinc/solvers/;${CI_PROJECT_DIR}/vendor/chuffed/share/minizinc/solvers
    BUILDCACHE_DIR: "$CI_PROJECT_DIR/.ccache"
    BUILDCACHE_MAX_CACHE_SIZE: "104857600"
  before_script:
    ### Choose the MiniZinc compiler branch
    - if defined CI_COMMIT_TAG (set MZNREF=%CI_COMMIT_TAG%) else if %CI_COMMIT_REF_NAME%==master (set MZNREF=master) else (set MZNREF=develop)
    ### Download Dependencies
    - curl --silent -o minizinc.zip --location --header "PRIVATE-TOKEN:%ACCESS_TOKEN%" "https://gitlab.com/api/v4/projects/minizinc%%2Fminizinc/jobs/artifacts/%MZNREF%/download?job=build:%MZNARCH%"
    - unzip -q minizinc.zip
    - curl --silent -o vendor.zip --location --header "PRIVATE-TOKEN:%ACCESS_TOKEN%" "https://gitlab.com/api/v4/projects/minizinc%%2Fminizinc-vendor/jobs/artifacts/master/download?job=bundle:%MZNARCH%"
    - unzip -q vendor.zip
    ### Add MiniZinc to path
    - set PATH=%CI_PROJECT_DIR%/minizinc/bin;%PATH%
  script:
    ### Build tests
    - if not exist "test" mkdir test
    - cd test
    - qmake "CXX_PREFIX=buildcache" ../tests/tests.pro
    - jom -j4
    ### Run tests
    - jom check
  tags: [win64, cpp, qt]
  cache:
    key: "test_win64"
    paths: [.ccache]

# ----------- MiniZinc Packaging -----------
.packaging_setup: &packaging_setup
  before_script:
    ### Set the MZNVERSION variable
    - 'if [ -n "$CI_COMMIT_TAG" ]; then MZNVERSION="$CI_COMMIT_TAG"; else MZNVERSION="build$CI_PIPELINE_ID"; fi'
    ### Choose the MiniZinc compiler branch
    - 'if [ -n "$CI_COMMIT_TAG" ]; then MZNREF="$CI_COMMIT_TAG"; elif [ "$CI_COMMIT_REF_NAME" = "master" ]; then MZNREF="master"; else MZNREF="develop"; fi'
    ### Choose the FindMUS branch
    - 'if  [ -n "$CI_COMMIT_TAG" ] || [ "$CI_COMMIT_REF_NAME" = "master" ]; then FINDMUSREF="master"; else FINDMUSREF="develop"; fi'
    ### Choose the FindMUS branch
    - 'if  [ -n "$CI_COMMIT_TAG" ] || [ "$CI_COMMIT_REF_NAME" = "master" ]; then ANALYSEREF="master"; else ANALYSEREF="develop"; fi'
    ### Download Dependencies
    - curl --silent -o minizinc.zip --location --header "PRIVATE-TOKEN:$ACCESS_TOKEN" "https://gitlab.com/api/v4/projects/minizinc%2Fminizinc/jobs/artifacts/$MZNREF/download?job=build:$MZNARCH"
    - unzip -q minizinc.zip
    - '[ ${DOWNLOAD_SOLVERS:-1} -eq 1 ] && curl --silent -o vendor.zip --location --header "PRIVATE-TOKEN:$ACCESS_TOKEN" "https://gitlab.com/api/v4/projects/minizinc%2Fminizinc-vendor/jobs/artifacts/master/download?job=bundle:$MZNARCH" && unzip -q vendor.zip'
    - '[ ${DOWNLOAD_GLOBALIZER:-0} -eq 1 ] && curl --silent -o globalizer.zip --location --header "PRIVATE-TOKEN:$ACCESS_TOKEN" "https://gitlab.com/api/v4/projects/minizinc%2FGlobalizer/jobs/artifacts/master/download?job=build:$MZNARCH" && unzip -q globalizer.zip'
    - '[ ${DOWNLOAD_FINDMUS:-0} -eq 1 ] && curl --silent -o findmus.zip --location --header "PRIVATE-TOKEN:$ACCESS_TOKEN" "https://gitlab.com/api/v4/projects/minizinc%2FFindMUS/jobs/artifacts/$FINDMUSREF/download?job=build:$MZNARCH" && unzip -q findmus.zip'
    - '[ ${DOWNLOAD_ANALYSE:-0} -eq 1 ] && curl --silent -o mzn-analyse.zip --location --header "PRIVATE-TOKEN:$ACCESS_TOKEN" "https://gitlab.com/api/v4/projects/minizinc%2Fmzn-analyse/jobs/artifacts/$ANALYSEREF/download?job=build:$MZNARCH" && unzip -q mzn-analyse.zip'

package:check_version:
  stage: package
  image: ghcr.io/minizinc/docker-build-environment:qt
  variables:
    MZNARCH: "linux"
    DOWNLOAD_SOLVERS: 0
  <<: *packaging_setup
  script:
    - mkdir -p build; cd build
    - qmake -makefile "CONFIG+=output_version" ../MiniZincIDE/MiniZincIDE.pro
    - IDE_VERSION=$(tr -s ' ' < version)
    - MZN_VERSION=$(../minizinc/bin/minizinc --version | grep -Po '(?<=version )[^,]+')
    - echo IDE is version ${IDE_VERSION}
    - echo MiniZinc is version ${MZN_VERSION}
    - if [ "$IDE_VERSION" != "$MZN_VERSION" ]; then echo 'Version mismatch!'; exit 1; fi
    - if [ -n "$CI_COMMIT_TAG" ]; then echo Tag is "$CI_COMMIT_TAG"; if [ "$CI_COMMIT_TAG" != "$MZN_VERSION" ]; then echo 'Version mismatch!'; exit 1; fi; fi
  needs: []
  tags: [linux, docker]

package:linux:
  stage: package
  image: ghcr.io/minizinc/docker-build-environment:package
  variables:
    MZNARCH: "linux"
    DOWNLOAD_GLOBALIZER: 1
    DOWNLOAD_FINDMUS: 1
    DOWNLOAD_ANALYSE: 1
  <<: *packaging_setup
  script:
    - PACKAGE=MiniZincIDE-${MZNVERSION}-bundle-linux-x86_64
    - mkdir -p $PACKAGE/lib/
    ### Package IDE
    - mv ide/usr/* $PACKAGE/
    - cp resources/scripts/MiniZincIDE.sh $PACKAGE/
    ### Package MiniZinc
    - mv minizinc/bin/* $PACKAGE/bin/
    - mv minizinc/share $PACKAGE/share
    ### Package vendor solvers
    - mv vendor/gecode_gist/bin/fzn-gecode $PACKAGE/bin/
    - patchelf --set-rpath '$ORIGIN/../lib' $PACKAGE/bin/fzn-gecode
    - cp -r vendor/gecode_gist/share/minizinc/* $PACKAGE/share/minizinc/
    - mv vendor/chuffed/bin/fzn-chuffed $PACKAGE/bin/
    - cp -r vendor/chuffed/share/minizinc/* $PACKAGE/share/minizinc/
    - mv vendor/or-tools/bin/fzn-cp-sat $PACKAGE/bin/
    - cp -r vendor/or-tools/share/minizinc/* $PACKAGE/share/minizinc/
    - cp vendor/highs/lib64/libhighs.so $PACKAGE/lib/
    ### Package Globalizer
    - mv globalizer/bin/minizinc-globalizer $PACKAGE/bin/
    - cp -r globalizer/share/minizinc/* $PACKAGE/share/minizinc/
    ### Package findMUS
    - mv findMUS/bin/findMUS $PACKAGE/bin/
    - cp -r findMUS/share/minizinc/* $PACKAGE/share/minizinc/
    ### Package mzn-analyse
    - mv mzn-analyse/bin/mzn-analyse $PACKAGE/bin/
    ### Strip included binaries
    - (cd $PACKAGE/bin; strip minizinc fzn-gecode fzn-chuffed fzn-cp-sat findMUS mzn-analyse minizinc-globalizer mzn2doc)
    - cp resources/misc/README $PACKAGE
    ### Compress package
    - tar -czf $PACKAGE.tgz $PACKAGE
    ### Generate checksum
    - sha256sum $PACKAGE.tgz > $PACKAGE.sha256
  artifacts:
    name: "minizinc_bundle_linux_${CI_PIPELINE_ID}"
    paths: [MiniZincIDE*.tgz, MiniZincIDE*.sha256]
  needs: ["build:linux"]
  tags: [linux, docker]

package:osx:
  stage: package
  variables:
    MZNARCH: "osx"
    DOWNLOAD_GLOBALIZER: 1
    DOWNLOAD_FINDMUS: 1
    DOWNLOAD_ANALYSE: 1
  <<: *packaging_setup
  script:
    - "DIR=MiniZincIDE.app/Contents/Resources; MZNDIR=$DIR/share/minizinc"
    - mkdir -p $MZNDIR/solvers
    ### Package MiniZinc
    - mv minizinc/bin/* $DIR/
    - mv minizinc/share/minizinc/* $MZNDIR/
    ### Package vendor solvers
    - mkdir -p $DIR/bin/
    - mkdir -p $DIR/lib/
    - mv vendor/gecode_gist/bin/fzn-gecode $DIR/bin/fzn-gecode
    - cp -r vendor/gecode_gist/share/minizinc/* $MZNDIR/
    - cp resources/misc/osx-gecode-qt.conf $DIR/bin/qt.conf
    - mv vendor/chuffed/bin/fzn-chuffed $DIR/bin/
    - cp -r vendor/chuffed/share/minizinc/* $MZNDIR/
    - mv vendor/or-tools/bin/fzn-cp-sat $DIR/bin/
    - cp -r vendor/or-tools/share/minizinc/* $MZNDIR/
    - cp vendor/highs/lib/libhighs.dylib $DIR/lib/
    ### Package Globalizer
    - mv globalizer/bin/minizinc-globalizer $DIR/bin/
    - cp -r globalizer/share/minizinc/* $MZNDIR/
    ### Package findMUS
    - mv findMUS/bin/findMUS $DIR/bin/
    - cp -r findMUS/share/minizinc/* $MZNDIR/
    ### Package mzn-analyse
    - mv mzn-analyse/bin/mzn-analyse $DIR/bin/
    ### Strip included binaries
    - (cd $DIR; strip minizinc mzn2doc)
    - (cd $DIR/bin; strip fzn-gecode fzn-chuffed fzn-cp-sat findMUS mzn-analyse minizinc-globalizer)
    ### Run automated Qt deployment tool
    - macdeployqt ./MiniZincIDE.app -executable=$DIR/bin/fzn-gecode
    ### Sign package
    - if [ -z "$OSX_DEVELOPER_ID" ]; then
    - exit 0
    - fi
    - security unlock-keychain -p "$OSX_KEYCHAIN_PASSWORD" "$OSX_KEYCHAIN_PATH"
    - security set-key-partition-list -S 'apple-tool:,apple:' -s -k "$OSX_KEYCHAIN_PASSWORD" "$OSX_KEYCHAIN_PATH"
    - security list-keychains -d user -s "$OSX_KEYCHAIN_PATH" login.keychain
    - for f in MiniZincIDE.app/Contents/Frameworks/*.framework; do \
    - codesign --options runtime --force --sign "$OSX_DEVELOPER_ID" $f/Versions/*/`basename $f .framework`; \
    - done
    - find MiniZincIDE.app/Contents/PlugIns MiniZincIDE.app/Contents/Frameworks -type f -name '*.dylib' -exec codesign --options runtime --force --sign "$OSX_DEVELOPER_ID" {} \;
    - find MiniZincIDE.app/Contents/Resources -type f -perm +111 -exec codesign --options runtime --entitlements resources/misc/entitlements.xml --force --sign "$OSX_DEVELOPER_ID" {} \;
    - codesign --options runtime --force --sign "$OSX_DEVELOPER_ID" MiniZincIDE.app
    - ditto -c -k --sequesterRsrc --keepParent MiniZincIDE.app signed_bundle.zip
    - xcrun notarytool submit signed_bundle.zip --team-id "$OSX_NOTARY_TOOL_TEAM_ID" --apple-id "$OSX_NOTARY_TOOL_APPLE_ID" --password "$OSX_NOTARY_TOOL_PASSWORD" --wait
    - xcrun stapler staple MiniZincIDE.app
    - cp "$OSX_TEMPLATE_IMAGE" signed_bundle.sparseimage
    - hdiutil detach -quiet signed_bundle || true
    - hdiutil attach -mountpoint signed_bundle signed_bundle.sparseimage
    - diskutil rename signed_bundle "MiniZinc IDE $MZNVERSION (bundled)"
    - rm -rf signed_bundle/MiniZincIDE.app
    - mv MiniZincIDE.app signed_bundle/
    - hdiutil detach signed_bundle
    - hdiutil convert -format UDZO -o MiniZincIDE-$MZNVERSION-bundled.dmg signed_bundle.sparseimage
  after_script:
    - hdiutil detach -quiet signed_bundle || true
    - security lock-keychain "$OSX_KEYCHAIN_PATH"
  artifacts:
    name: "minizinc_bundle_mac_${CI_PIPELINE_ID}"
    paths: [MiniZincIDE.app, MiniZincIDE-*-bundled.dmg]
  needs: ["build:osx"]
  tags: [osx, qt]

package:osx:ide_only:
  stage: package
  variables:
    MZNARCH: "osx"
  script:
    ### Run automated Qt deployment tool
    - macdeployqt ./MiniZincIDE.app
  artifacts:
    name: "minizinc_ide_mac_${CI_PIPELINE_ID}"
    paths: [MiniZincIDE.app]
  needs: ["build:osx"]
  tags: [osx, qt]

package:win64:
  stage: package
  variables:
    MZNARCH: "win64"
    ISSARCH: "x64"
    ISSARCHALLOWED: "x64"
    CODESIGN_CMD: signtool.exe sign /fd SHA256 /tr http://timestamp.acs.microsoft.com /td SHA256 /dlib $WIN_CODESIGN_DLIB /dmdf $WIN_CODESIGN_METADATA
  before_script:
    ### Set redist variables
    - for /d %%a in ("%VCToolsRedistDir%\\x64\\*.CRT") do set MSVCREDIST=%%a
    - set UCRTREDIST=%WindowsSdkDir%\Redist\ucrt\DLLs\x64
    ### Set the MZNVERSION variable
    - if defined CI_COMMIT_TAG (set MZNVERSION=%CI_COMMIT_TAG%) else (set MZNVERSION=%CI_PIPELINE_ID%)
    ### Choose the MiniZinc compiler branch
    - if defined CI_COMMIT_TAG (set MZNREF=%CI_COMMIT_TAG%) else if %CI_COMMIT_REF_NAME%==master (set MZNREF=master) else (set MZNREF=develop)
    - if defined CI_COMMIT_TAG (set FINDMUSREF=master) else if %CI_COMMIT_REF_NAME%==master (set FINDMUSREF=master) else (set FINDMUSREF=develop)
    - if defined CI_COMMIT_TAG (set ANALYSEREF=master) else if %CI_COMMIT_REF_NAME%==master (set ANALYSEREF=master) else (set ANALYSEREF=develop)
    ### Download Dependencies
    - curl --silent -o minizinc.zip --location --header "PRIVATE-TOKEN:%ACCESS_TOKEN%" "https://gitlab.com/api/v4/projects/minizinc%%2Fminizinc/jobs/artifacts/%MZNREF%/download?job=build:%MZNARCH%"
    - unzip -q minizinc.zip
    - curl --silent -o vendor.zip --location --header "PRIVATE-TOKEN:%ACCESS_TOKEN%" "https://gitlab.com/api/v4/projects/minizinc%%2Fminizinc-vendor/jobs/artifacts/master/download?job=bundle:%MZNARCH%"
    - unzip -q vendor.zip
    - curl --silent -o globalizer.zip --location --header "PRIVATE-TOKEN:%ACCESS_TOKEN%" "https://gitlab.com/api/v4/projects/minizinc%%2Fglobalizer/jobs/artifacts/master/download?job=build:%MZNARCH%"
    - unzip -q globalizer.zip
    - curl --silent -o findmus.zip --location --header "PRIVATE-TOKEN:%ACCESS_TOKEN%" "https://gitlab.com/api/v4/projects/minizinc%%2FFindMus/jobs/artifacts/%FINDMUSREF%/download?job=build:%MZNARCH%"
    - unzip -q findmus.zip
    - curl --silent -o mzn-analyse.zip --location --header "PRIVATE-TOKEN:%ACCESS_TOKEN%" "https://gitlab.com/api/v4/projects/minizinc%%2Fmzn-analyse/jobs/artifacts/%ANALYSEREF%/download?job=build:%MZNARCH%"
    - unzip -q mzn-analyse.zip
    ### Turn on code signing if variables present
    - if defined WIN_CODESIGN_METADATA (set DOCODESIGN=1) else (set DOCODESIGN=0)
  script:
    - '"C:/Program Files (x86)/Inno Setup 6/ISCC.exe" /dMyAppVersion="%MZNVERSION%" /dMyMZNVersion="%MZNVERSION%" /dMyAppDirectory="%CI_PROJECT_DIR%" /dMyMSVCRedist="%MSVCREDIST%" /dMyUCRTRedist="%UCRTREDIST%" /dMyAPPArch="%MZNARCH%" /dMyApp64Bit="%ISSARCH%" /dMyAppArchitectures="%ISSARCHALLOWED%" /dDoCodeSign="%DOCODESIGN%" /SMyCodeSignTool="%CODESIGN_CMD% $f" /O"%CI_PROJECT_DIR%" resources/pkg_config/minizinc-bundle.iss'
    ### Generate checksum
    - certutil -hashfile MiniZincIDE-%MZNVERSION%-bundled-setup-%MZNARCH%.exe SHA256 > MiniZincIDE-%MZNVERSION%-bundled-setup-%MZNARCH%.sha256
  artifacts:
    name: "minizinc_bundle_windows_%CI_PIPELINE_ID%"
    paths: [MiniZincIDE*.exe, MiniZincIDE*.sha256]
  needs: ["build:win64"]
  tags: [win64]

package:appimage:
  stage: package
  image: ghcr.io/minizinc/docker-build-environment:qt
  variables:
    MZNARCH: "linux"
    DOWNLOAD_GLOBALIZER: 1
    DOWNLOAD_FINDMUS: 1
    DOWNLOAD_ANALYSE: 1
    PACKAGE: "MiniZinc.AppDir"
  <<: *packaging_setup
  script:
    - mkdir -p $PACKAGE/usr/lib
    ### Package IDE
    - mv ide/usr/* $PACKAGE/usr/
    ### Package MiniZinc
    - mv minizinc/bin/* $PACKAGE/usr/bin/
    - mv minizinc/share $PACKAGE/usr/share
    ### Package vendor solvers
    - mv vendor/gecode_gist/bin/fzn-gecode $PACKAGE/usr/bin/
    - cp -r vendor/gecode_gist/share/minizinc/* $PACKAGE/usr/share/minizinc/
    - mv vendor/chuffed/bin/fzn-chuffed $PACKAGE/usr/bin/
    - cp -r vendor/chuffed/share/minizinc/* $PACKAGE/usr/share/minizinc/
    - mv vendor/or-tools/bin/fzn-cp-sat $PACKAGE/usr/bin/
    - cp -r vendor/or-tools/share/minizinc/* $PACKAGE/usr/share/minizinc/
    - cp vendor/highs/lib64/libhighs.so $PACKAGE/usr/lib/
    ### Package Globalizer
    - mv globalizer/bin/minizinc-globalizer $PACKAGE/usr/bin/
    - cp -r globalizer/share/minizinc/* $PACKAGE/usr/share/minizinc/
    ### Package findMUS
    - mv findMUS/bin/findMUS $PACKAGE/usr/bin/
    - cp -r findMUS/share/minizinc/* $PACKAGE/usr/share/minizinc/
    ### Package mzn-analyse
    - mv mzn-analyse/bin/mzn-analyse $PACKAGE/usr/bin/
    ### Strip included binaries
    - (cd $PACKAGE/usr/bin; strip minizinc fzn-gecode fzn-chuffed fzn-cp-sat findMUS mzn-analyse minizinc-globalizer mzn2doc)
    - cp resources/misc/README $PACKAGE
    ### Assemble AppImage
    - cp resources/scripts/AppRun $PACKAGE
    - cp resources/misc/minizinc.desktop $PACKAGE/minizinc.desktop
    - cp resources/icon.png $PACKAGE/minizinc.png
    - ARCH=x86_64 appimagetool $PACKAGE MiniZincIDE-${MZNVERSION}-x86_64.AppImage
    ### Generate checksum
    - sha256sum MiniZincIDE*.AppImage > MiniZincIDE-${MZNVERSION}-x86_64.sha256
  artifacts:
    name: "minizinc_appimage_${CI_PIPELINE_ID}"
    paths: [MiniZincIDE*.AppImage, MiniZincIDE*.sha256]
  needs: ["build:linux"]
  tags: [linux, docker]

.docker_setup: &docker_setup
  image: ghcr.io/minizinc/docker-build-environment:docker-cli
  before_script:
    ### Set the MZNVERSION variable
    - 'if [ -n "$CI_COMMIT_TAG" ]; then MZNVERSION="$CI_COMMIT_TAG"; else MZNVERSION="build$CI_PIPELINE_ID"; fi'
    ### Choose the MiniZinc compiler branch
    - 'if [ -n "$CI_COMMIT_TAG" ]; then MZNREF="$CI_COMMIT_TAG"; elif [ "$CI_COMMIT_REF_NAME" = "master" ]; then MZNREF="master"; else MZNREF="develop"; fi'
    ### Download Dependencies
    - mkdir -p linux/amd64 && cd linux/amd64
    - curl --silent -o minizinc.zip --location --header "PRIVATE-TOKEN:$ACCESS_TOKEN" "https://gitlab.com/api/v4/projects/minizinc%2Fminizinc/jobs/artifacts/$MZNREF/download?job=build:$MZNARCH" && unzip -q minizinc.zip
    - curl --silent -o vendor.zip --location --header "PRIVATE-TOKEN:$ACCESS_TOKEN" "https://gitlab.com/api/v4/projects/minizinc%2Fminizinc-vendor/jobs/artifacts/master/download?job=bundle:$MZNARCH" && unzip -q vendor.zip
    - mkdir -p ../arm64 && cd ../arm64
    - curl --silent -o minizinc.zip --location --header "PRIVATE-TOKEN:$ACCESS_TOKEN" "https://gitlab.com/api/v4/projects/minizinc%2Fminizinc/jobs/artifacts/$MZNREF/download?job=build:$MZNARCH-arm64" && unzip -q minizinc.zip
    - curl --silent -o vendor.zip --location --header "PRIVATE-TOKEN:$ACCESS_TOKEN" "https://gitlab.com/api/v4/projects/minizinc%2Fminizinc-vendor/jobs/artifacts/master/download?job=bundle:$MZNARCH-arm64" && unzip -q vendor.zip
    - cd ../../

package:docker_alpine:
  stage: package
  variables:
    MZNARCH: "musl"
  <<: *docker_setup
  script:
    - echo "Building image based on \"alpine:latest\" with tag extension \"-alpine\""
    - if [ -n "$CI_COMMIT_TAG" ]; then IMAGE_TAG="minizinc/minizinc:${CI_COMMIT_TAG}-alpine"; fi
    - if [ "$CI_COMMIT_REF_NAME" = "master" ]; then IMAGE_TAG=minizinc/minizinc:latest-alpine; fi
    - if [ "$CI_COMMIT_REF_NAME" = "develop" ]; then IMAGE_TAG=minizinc/minizinc:edge-alpine; fi
    - if [ -n "$IMAGE_TAG" ]; then BUILDX_ARGS="--push -t $IMAGE_TAG"; fi
    - docker buildx build $BUILDX_ARGS --pull --builder=container --platform=linux/amd64,linux/arm64 -f resources/pkg_config/Dockerfile --build-arg BASE='alpine:latest' .
  needs: []
  tags: [linux-arm64, mac-mini]

package:docker_ubuntu:
  stage: package
  parallel: 3
  variables:
    MZNARCH: "linux"
  <<: *docker_setup
  script:
    - BASES=("null" "ubuntu:latest" "ubuntu:noble" "ubuntu:jammy")
    - EXTS=("null" "" "-noble" "-jammy")
    - echo "Building image based on \"${BASES[$CI_NODE_INDEX]}\" with tag extension \"${EXTS[$CI_NODE_INDEX]}\""
    - if [ -n "$CI_COMMIT_TAG" ]; then IMAGE_TAG=minizinc/minizinc:${CI_COMMIT_TAG}${EXTS[$CI_NODE_INDEX]}; fi
    - if [ "$CI_COMMIT_REF_NAME" = "master" ]; then IMAGE_TAG=minizinc/minizinc:latest${EXTS[$CI_NODE_INDEX]}; fi
    - if [ "$CI_COMMIT_REF_NAME" = "develop" ]; then IMAGE_TAG=minizinc/minizinc:edge${EXTS[$CI_NODE_INDEX]}; fi
    - if [ -n "$IMAGE_TAG" ]; then BUILDX_ARGS="--push -t $IMAGE_TAG"; fi
    - docker buildx build $BUILDX_ARGS --pull --builder=container --platform=linux/amd64,linux/arm64 -f resources/pkg_config/Dockerfile --build-arg BASE=${BASES[$CI_NODE_INDEX]} .
  needs: []
  tags: [linux-arm64, mac-mini]

minizinc:linux:nogui:
  image: ghcr.io/minizinc/docker-build-environment:package
  stage: package
  variables:
    MZNARCH: "linux"
  <<: *packaging_setup
  script:
    - PACKAGE=MiniZinc-${MZNVERSION}-linux-x86_64
    - mkdir -p $PACKAGE/bin
    - mkdir -p $PACKAGE/lib
    ### Package MiniZinc
    - mv minizinc/bin/* $PACKAGE/bin/
    - mv minizinc/share $PACKAGE/share
    ### Package vendor solvers
    - mv vendor/gecode/bin/fzn-gecode $PACKAGE/bin/
    - cp -r vendor/gecode/share/minizinc/* $PACKAGE/share/minizinc/
    - mv vendor/chuffed/bin/fzn-chuffed $PACKAGE/bin/
    - cp -r vendor/chuffed/share/minizinc/* $PACKAGE/share/minizinc/
    - mv vendor/or-tools/bin/fzn-cp-sat $PACKAGE/bin/
    - cp -r vendor/or-tools/share/minizinc/* $PACKAGE/share/minizinc/
    - cp vendor/highs/lib64/libhighs.so $PACKAGE/lib/
    ### Strip included binaries
    - (cd $PACKAGE/bin; strip minizinc fzn-gecode fzn-chuffed fzn-cp-sat mzn2doc)
    ### Compress package
    - tar -czf $PACKAGE.tar.gz $PACKAGE
  artifacts:
    name: "minizinc_linux_nogui_${CI_PIPELINE_ID}"
    paths: [MiniZinc*.tar.gz]
  needs: []
  tags: [linux, docker]

.snap_job: &snap_job
  stage: package
  image: ghcr.io/minizinc/docker-build-environment:snap
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
    MZNARCH: "linux"
    DOWNLOAD_GLOBALIZER: 1
    DOWNLOAD_FINDMUS: 1
    DOWNLOAD_ANALYSE: 1
  <<: *packaging_setup
  script:
    - strip minizinc/bin/minizinc vendor/gecode_gist/bin/fzn-gecode vendor/chuffed/bin/fzn-chuffed vendor/or-tools/bin/fzn-cp-sat findMUS/bin/findMUS mzn-analyse/bin/mzn-analyse globalizer/bin/minizinc-globalizer minizinc/bin/mzn2doc
    - cp resources/pkg_config/snapcraft.yaml .
    - apt-get update -y
    - snapcraft --destructive-mode
  artifacts:
    name: "minizinc_snap_${CI_PIPELINE_ID}"
    paths: [minizinc*.snap]
  needs: ["build:linux"]
  tags: [linux, docker]

package:snap:
  <<: *snap_job
  only: [tags, master, develop]

package:snap_manual:
  <<: *snap_job
  except: [tags, master, develop]
  when: manual

.snap_publish: &snap_publish
  stage: publish
  image: ghcr.io/minizinc/docker-build-environment:snap
  tags: [linux, docker]
  script:
    - snapcraft upload minizinc*.snap --release $SNAPCRAFT_CHANNEL
  needs: ["package:snap"]

publish:snap_edge:
  variables:
    SNAPCRAFT_CHANNEL: edge
  <<: *snap_publish
  only: [develop]

publish:snap_stable:
  variables:
    SNAPCRAFT_CHANNEL: stable
  <<: *snap_publish
  only: [tags]
  when: manual # Don't publish to stable channel automatically

publish:github_edge:
  stage: publish
  image: ghcr.io/minizinc/docker-build-environment:package
  variables:
    REMOTE_URL: https://minizinc-ci:${ACCESS_TOKEN}@gitlab.com/minizinc/minizinc-ide.git
  script:
    # Update edge tag
    - git config user.name "$GITLAB_USER_NAME"
    - git config user.email "$GITLAB_USER_EMAIL"
    - git remote add gitlab_remote "${REMOTE_URL}" || git remote set-url gitlab_remote "${REMOTE_URL}"
    - git tag -f -a -m "Development build of MiniZinc" edge
    - git push -f gitlab_remote edge -o ci.skip
    # Remove old assets
    - gh release --repo MiniZinc/MiniZincIDE view edge --json assets --jq '.assets[].name' | xargs -n 1 -r gh release --repo MiniZinc/MiniZincIDE delete-asset -y edge
    # Upload new assets
    - gh release --repo MiniZinc/MiniZincIDE upload edge MiniZincIDE*.dmg MiniZincIDE*.exe MiniZincIDE*.AppImage MiniZincIDE*.tgz MiniZincIDE*.sha256
  needs: ["package:osx", "package:win64", "package:appimage", "package:linux"]
  only: [develop]
  tags: [linux, docker]

publish:github_stable:
  stage: publish
  image: ghcr.io/minizinc/docker-build-environment:package
  script:
    - NOTES="This release"
    - '[ "$(echo "$CI_COMMIT_TAG" | cut -d. -f3)" == "0" ] && NOTES="$NOTES adds several new features and"'
    - NOTES="$NOTES fixes a number of bugs, see https://docs.minizinc.dev/en/${CI_COMMIT_TAG}/changelog.html for a full change log. Binary releases for different platforms are available in the bundled packages of the MiniZinc IDE at https://github.com/minizinc/minizincide/releases."
    - gh release --repo MiniZinc/libminizinc create --draft --title "MiniZinc $CI_COMMIT_TAG" --notes "$NOTES" "$CI_COMMIT_TAG"
    - echo "Please refer to the change log for details:" > ide_notes
    - echo "https://docs.minizinc.dev/en/${CI_COMMIT_TAG}/changelog.html" >> ide_notes
    - gh release --repo MiniZinc/MiniZincIDE create --draft --title "MiniZinc $CI_COMMIT_TAG" --notes-file ide_notes "$CI_COMMIT_TAG" MiniZincIDE*.dmg MiniZincIDE*.exe MiniZincIDE*.AppImage MiniZincIDE*.tgz MiniZincIDE*.sha256
  needs: ["package:osx", "package:win64", "package:appimage", "package:linux"]
  only: [tags]
  except: [edge]
  tags: [linux, docker]


================================================
FILE: LICENSE.txt
================================================
Mozilla Public License Version 2.0
==================================

1. Definitions
--------------

1.1. "Contributor"
    means each individual or legal entity that creates, contributes to
    the creation of, or owns Covered Software.

1.2. "Contributor Version"
    means the combination of the Contributions of others (if any) used
    by a Contributor and that particular Contributor's Contribution.

1.3. "Contribution"
    means Covered Software of a particular Contributor.

1.4. "Covered Software"
    means Source Code Form to which the initial Contributor has attached
    the notice in Exhibit A, the Executable Form of such Source Code
    Form, and Modifications of such Source Code Form, in each case
    including portions thereof.

1.5. "Incompatible With Secondary Licenses"
    means

    (a) that the initial Contributor has attached the notice described
        in Exhibit B to the Covered Software; or

    (b) that the Covered Software was made available under the terms of
        version 1.1 or earlier of the License, but not also under the
        terms of a Secondary License.

1.6. "Executable Form"
    means any form of the work other than Source Code Form.

1.7. "Larger Work"
    means a work that combines Covered Software with other material, in 
    a separate file or files, that is not Covered Software.

1.8. "License"
    means this document.

1.9. "Licensable"
    means having the right to grant, to the maximum extent possible,
    whether at the time of the initial grant or subsequently, any and
    all of the rights conveyed by this License.

1.10. "Modifications"
    means any of the following:

    (a) any file in Source Code Form that results from an addition to,
        deletion from, or modification of the contents of Covered
        Software; or

    (b) any new file in Source Code Form that contains any Covered
        Software.

1.11. "Patent Claims" of a Contributor
    means any patent claim(s), including without limitation, method,
    process, and apparatus claims, in any patent Licensable by such
    Contributor that would be infringed, but for the grant of the
    License, by the making, using, selling, offering for sale, having
    made, import, or transfer of either its Contributions or its
    Contributor Version.

1.12. "Secondary License"
    means either the GNU General Public License, Version 2.0, the GNU
    Lesser General Public License, Version 2.1, the GNU Affero General
    Public License, Version 3.0, or any later versions of those
    licenses.

1.13. "Source Code Form"
    means the form of the work preferred for making modifications.

1.14. "You" (or "Your")
    means an individual or a legal entity exercising rights under this
    License. For legal entities, "You" includes any entity that
    controls, is controlled by, or is under common control with You. For
    purposes of this definition, "control" means (a) the power, direct
    or indirect, to cause the direction or management of such entity,
    whether by contract or otherwise, or (b) ownership of more than
    fifty percent (50%) of the outstanding shares or beneficial
    ownership of such entity.

2. License Grants and Conditions
--------------------------------

2.1. Grants

Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:

(a) under intellectual property rights (other than patent or trademark)
    Licensable by such Contributor to use, reproduce, make available,
    modify, display, perform, distribute, and otherwise exploit its
    Contributions, either on an unmodified basis, with Modifications, or
    as part of a Larger Work; and

(b) under Patent Claims of such Contributor to make, use, sell, offer
    for sale, have made, import, and otherwise transfer either its
    Contributions or its Contributor Version.

2.2. Effective Date

The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.

2.3. Limitations on Grant Scope

The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:

(a) for any code that a Contributor has removed from Covered Software;
    or

(b) for infringements caused by: (i) Your and any other third party's
    modifications of Covered Software, or (ii) the combination of its
    Contributions with other software (except as part of its Contributor
    Version); or

(c) under Patent Claims infringed by Covered Software in the absence of
    its Contributions.

This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).

2.4. Subsequent Licenses

No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).

2.5. Representation

Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.

2.6. Fair Use

This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.

2.7. Conditions

Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.

3. Responsibilities
-------------------

3.1. Distribution of Source Form

All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.

3.2. Distribution of Executable Form

If You distribute Covered Software in Executable Form then:

(a) such Covered Software must also be made available in Source Code
    Form, as described in Section 3.1, and You must inform recipients of
    the Executable Form how they can obtain a copy of such Source Code
    Form by reasonable means in a timely manner, at a charge no more
    than the cost of distribution to the recipient; and

(b) You may distribute such Executable Form under the terms of this
    License, or sublicense it under different terms, provided that the
    license for the Executable Form does not attempt to limit or alter
    the recipients' rights in the Source Code Form under this License.

3.3. Distribution of a Larger Work

You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).

3.4. Notices

You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.

3.5. Application of Additional Terms

You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.

4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------

If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.

5. Termination
--------------

5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.

5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.

5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.

************************************************************************
*                                                                      *
*  6. Disclaimer of Warranty                                           *
*  -------------------------                                           *
*                                                                      *
*  Covered Software is provided under this License on an "as is"       *
*  basis, without warranty of any kind, either expressed, implied, or  *
*  statutory, including, without limitation, warranties that the       *
*  Covered Software is free of defects, merchantable, fit for a        *
*  particular purpose or non-infringing. The entire risk as to the     *
*  quality and performance of the Covered Software is with You.        *
*  Should any Covered Software prove defective in any respect, You     *
*  (not any Contributor) assume the cost of any necessary servicing,   *
*  repair, or correction. This disclaimer of warranty constitutes an   *
*  essential part of this License. No use of any Covered Software is   *
*  authorized under this License except under this disclaimer.         *
*                                                                      *
************************************************************************

************************************************************************
*                                                                      *
*  7. Limitation of Liability                                          *
*  --------------------------                                          *
*                                                                      *
*  Under no circumstances and under no legal theory, whether tort      *
*  (including negligence), contract, or otherwise, shall any           *
*  Contributor, or anyone who distributes Covered Software as          *
*  permitted above, be liable to You for any direct, indirect,         *
*  special, incidental, or consequential damages of any character      *
*  including, without limitation, damages for lost profits, loss of    *
*  goodwill, work stoppage, computer failure or malfunction, or any    *
*  and all other commercial damages or losses, even if such party      *
*  shall have been informed of the possibility of such damages. This   *
*  limitation of liability shall not apply to liability for death or   *
*  personal injury resulting from such party's negligence to the       *
*  extent applicable law prohibits such limitation. Some               *
*  jurisdictions do not allow the exclusion or limitation of           *
*  incidental or consequential damages, so this exclusion and          *
*  limitation may not apply to You.                                    *
*                                                                      *
************************************************************************

8. Litigation
-------------

Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.

9. Miscellaneous
----------------

This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.

10. Versions of the License
---------------------------

10.1. New Versions

Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.

10.2. Effect of New Versions

You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.

10.3. Modified Versions

If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).

10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses

If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.

Exhibit A - Source Code Form License Notice
-------------------------------------------

  This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.

If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.

You may add additional accurate notices of copyright ownership.

Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------

  This Source Code Form is "Incompatible With Secondary Licenses", as
  defined by the Mozilla Public License, v. 2.0.


================================================
FILE: MiniZincIDE/CHANGES
================================================
2026-04-30
  v2.9.7
-  Update to MiniZinc 2.9.7.

2026-04-24
  v2.9.6
-  Fix syntax highlighting of the `list` keyword (#227).

2026-01-23
  v2.9.5
-  Update to MiniZinc 2.9.5.

2025-09-29
  v2.9.4
-  Update to MiniZinc 2.9.4.

2025-05-23
  v2.9.3
-  Suppress warnings generated when running compiled solution checkers.

2025-03-06
  v2.9.2
-  Fix the packaging of the OR Tools solver on linux distributions.

2025-03-03
  v2.9.1
-  Ensure locations for warnings and errors are shown when the stack dump is empty (#212).
-  Use scroll buttons when the tab bar overflows to ensure the side panels can be resized (#213).

2025-02-11
  v2.9.0
-  Fix broken documentation link in the help menu item.

2024-10-02
  v2.8.7
-  Update to MiniZinc 2.8.7.

2024-09-25
  v2.8.6
-  Update to MiniZinc 2.8.6.

2024-05-03
  v2.8.5
-  Update to MiniZinc 2.8.5.

2024-05-10
  v2.8.4
-  Fix bundled OpenSSL libraries on Windows.
-  Allow MOOC submission window to be scrolled.
-  Increase hard process termination timeout to 1s.

2024-02-01
  v2.8.3
-  Increase maximum number of threads from default Qt limit (#196).

2023-12-15
  v2.8.2
-  Make process handling more robust to failures.

2023-11-27
  v2.8.1
-  Fix command used to run findMUS and Globalizer.
-  Add ability to set the ports used for the visualisation server.
-  Add option for printing the visualisation server URL for debugging purposes.
-  Add more information to subprocess error messages.

2023-11-16
  v2.8.0
-  Fix unreadable cheat sheet font colour in dark mode (#191).
-  Add option to output objective value and enable by default.
-  Show manually input parameters in output window.
-  Fix missing checker messages (#192).
-  Fix incorrect OpenSSL version in Linux packages (#189).

2023-05-20
  v2.7.6
-  Update to MiniZinc 2.7.6.

2023-06-07
  v2.7.5
-  Use native Qt dark mode on Windows where supported.
-  Improve behaviour of the custom solver parameter dialog.

2023-05-11
  v2.7.4
-  Update to MiniZinc 2.7.4.

2023-04-20
  v2.7.3
-  Only show MOOC error code when response is actually an error (#176).

2023-04-05
  v2.7.2
-  Fix patching of `RPATH` for binaries and libraries in Snap package.

2023-03-31
  v2.7.1
-  Fix highlighting of multiline comments starting with /*/ (#172).
-  Fix bundling of incompatible OpenSSL version in linux packages.
-  Remove support for glibc 2.27 and earlier from AppImage and tarball linux
   packages. The Snap package may be used instead on such systems.

2023-02-23
  v2.7.0
-  Fix a bug where model selection dialog could run the wrong model.
-  Fix a bug where the same data file could be added to the MiniZinc command twice.
-  Ensure user config directory is created when modifying solver search paths (#167).
-  Ensure that IDE windows cannot spawn off-screen.
-  Add tooltips to the CP-Profiler status bar legend.
-  Add support for mooc submissions which include file editing history.

2022-06-23
  v2.6.4
-  Ensure the extra parameter filter is cleared when the textbox is cleared.

2022-05-06
  v2.6.3
-  Improve UI and dark mode for CP Profiler.
-  Fix CP Profiler tree-builder signal/slot connection (#160).
-  Fix deadlock in CP Profiler tree building (#162).
-  Make project loading more resilient to errors (#165).

2022-03-22
  v2.6.2
-  Don't print expected error messages for MOOC submissions.
-  Fix custom parameter widget dark mode CSS.

2022-03-03
  v2.6.1
-  Fix crash when the solver for an unsaved configuration is removed.
-  Fix bug where the selected solver could incorrectly change when a
    configuration option is altered.

2022-02-18
  v2.6.0
-  Add support for specifying submission terms for MOOC.
-  Ensure newly loaded configs override synced options (#144).
-  Fix check for empty project to avoid incorrect warnings when closing.
-  Maintain modified solver configurations when using preferences dialog.
-  Support using arm64 version of MiniZinc with x86_64 IDE build on macOS.
-  Fix crash when no solver configurations are available.
-  Remove WebEngine-based visualisation feature and implement HTTP/WebSocket
   server based visualisations.
-  Add support for dark mode detection on Windows.
-  Implement foldable output widget supporting output sections.
-  Support both Qt 5 and Qt 6.
-  Allow tab to shift multiple lines right.
-  Re-implement support for detached solver processes.
-  Allow the project/solver configuration panes to take the full height of the
   main window.
-  Implement new multi-tabbed preferences dialog.
-  Ignore errors in non-current files during background code checking.
-  Fix undefined behaviour in main window event filter (#154).
-  Fix crash when terminating solvers due to closing the main window.
-  Confirm before removing files from project (#149).

2021-03-19
  v2.5.5
-  Fix editing of custom string parameters so they don't get converted to
   floats.
-  Fix crash on Windows caused when the PATH environment contains unicode
   characters.

2021-03-16
  v2.5.4
-  Fix possible crash due to incorrect use of WriteFile on Windows.
-  Ensure Gecode Gist dependencies are present in the Linux bundle and AppImage
   (#132).
-  Fix crash when stopping solver during exit.
-  Don't show irrelevant context menu entries in the project explorer.
-  Add support for HTTP/S links in the output pane.
-  Fix crash when saving CP Profiler executions where there is no info
   associated with a node.
-  Show a warning when there are open files which are not part of a MOOC
   submission.
-  Fix double spinbox precision issues (#134).
-  Include Gecode Gist and CP Profiler dependencies in Snap package.
-  Allow opening of multiple files through the open file menu option.
-  Ensure file dialogs save last path when opening files.
-  Make the escape key close the find/replace dialog when focussed on any child
   widget.
-  Allow setting MOOC submission items as mandatory.

2020-24-06
  v2.5.3
-  Only reset config window item focus if it is still focused, preventing spurious
   changes in focus during code checking.
-  Fix handling of final statuses, including UNSAT (#123).
-  Remove -s flag support from Gecode Gist solver configuration (#125).
-  Fix crash when saving a project with no solver selected (#127).
-  Correctly remove temporary parameter configuration files after use (#128, #129).
-  Fix the time limit readout in the status bar when solving.

2020-11-06
  v2.5.2
  - Properly resize extra flags table after adding parameters (#119).
  - Use the minimal configuration to check the model interface (#118).
  - Allow omitting builtin solver version in project JSON.
  - Don't mark as modified when loading non-synced solver configurations.
  - Ensure the last open configuration in a project is selected when loaded.
  - Fix the default values of solution truncation and output window clearing.
  - Process unrecognised extra flags from old project configurations.
  - Fix watching for modification of the additional data box.
  - Fix the alignment of line numbers.
  - Make behaviour controls more narrow to accommodate smaller window sizes.
  - Defocus config window widgets when updating solver config so values of
    currently edited fields are updated.
  - Pass user input data correctly during compilation.
  - Remove solns2out options from MiniZinc call when compiling.

2020-10-22
  v2.5.1
  - Fix typo when passing solver statistics option to minizinc (#112).
  - Fix missing statistics output (#112).
  - Add support for colour themes (#110).
  - Don't prompt for saving after adding/removing files from the Untitled
    project.
  - Fix running of compiled FlatZinc files.
  - Show error message when trying to load an invalid configuration file.
  - Ensure all output is sent to the output console, and that fragments in
    standard error output appear when a newline is written to standard output
    (#114).
  - Fix running of solver configurations from the project explorer.
  - Improve performance of adding a large number of extra flags at once.
  - Add support for 64-bit integer extra flags.
  - Add support for setting both solver backend flags and MiniZinc command flags
    (#113).
  - Improve interface for adding extra parameters, allowing search/filter and
    multiselection of known parameters.

2020-09-25
  v2.5.0
  - Add fallback libraries if user does not have libnss3.
  - Remove support for the old binary storage format of projects used prior to
    version 2.2.0.
    These must be opened and re-saved with version 2.4.3 to remain compatible.
  - Include experimental CP-profiler through the *MiniZinc* > *Profile search*
    option for supported solvers.
  - Redesign the solver configuration window.
  - Use parameter configuration files rather than passing command-line options
    directly.
  - Show solver configurations and checkers in their own sections in the
    project explorer.
  - Allow multiselection in the project explorer for running particular sets
    of files.
  - Allow MiniZinc to manage subprocesses by itself.
  - Allow non-privileged installs of the IDE on Windows.
  - Correctly remove files from old installations of the IDE on Windows.
  - Enable scroll bars in the preferences dialog to allow for low resolution
    displays.
  - Prompt to save modified files before performing MOOC submissions or running
    models.
  - Fix infinite recursion when a model file for a MOOC submission doesn't
    exist.
  - Use --output-mode checker for MOOC solution submission where supported.
  - Fully support unicode on Windows.

2020-03-03
  v2.4.3
  - Disable menu items that don't make sense when all tabs are closed,
    fix behaviour of stop button when all tabs closed (fixes several crashes).
  - Add x86_64 suffix to linux package name (#96).
  - Make boolean extra solver options with a default of true functional.
  - Only read linter results if it exited normally (#97).
  - Update alpine version to 3.11
  - Resolve paths in _mooc to paths
    (allowing submission of models in subdirectories).
2020-01-10
  v2.4.2
  - Fix syntax highlighting of keywords, and add syntax highlighting for
    interpolated strings.
  - Redraw when switching to/from dark mode, and fix dark mode header colours.
  - Fix "Select all" menu item.
2019-12-09
  v2.4.1
  - Display error message when submission to MOOC provider fails.
  - Fix shift left and shift right indentation behaviour when selecting
    text backwards.
  - Make "previous tab" and "next tab" actions cycle rather than stop at
    first/last tab.
  - Fix OpenSSL library in binary distribution to enable update checks and
    submission to MOOCs again.
  v2.4.0
  - Parse timing and statistics output produced by compiler, and display as
    profiling information next to each line in the model.
  - Enable run/compile action on data files. This automatically selects the
    model file if there is only one, or presents a dialog for selecting the
    model if there are multiple.
  - Select first data file in parameter dialog if there was no previous
    selection, and always focus parameter dialog.
  - Fix dark mode detection on macOS 10.15, improve dark mode colors a bit
    and fixed some dark mode bugs.
  - Make background compilation of a model (used to display syntax and type
    errors) a bit more stable.
  - Highlight current line.
  - Support .json as file extension for data files.
  - Remember whether wrap around, case sensitivity and regular expression
    was selected in find/replace dialog, pre-select the find/replace text
    when find/replace widget is openend, and close find/replace widget when
    ESC is pressed while editor has focus.
  - Avoid infinite loop in wrap around replace all.
  - Fix memory management for HTML visualisation windows, and resize docked
    HTML visualisation widgets to take up equal space.
2019-09-12
  v2.3.2
  - Update to MiniZinc 2.3.2.
2019-07-10
  v2.3.1
  - Remove incorrect symbolic link and fix qt.conf for some bundled distributions.
  - Fix check for availability of dark mode on older versions of macOS.
  - Fix a typo in the cheat sheet.
  - Provide more robust solution for checking the model parameters, which will get
    rid of some "internal error" messages.
  - Always show directory selection dialog in the Windows installer. Addresses #89.
  - Improved the configuration files for some bundled solvers, provides nicer
    configuration interface.
2019-06-26
  v2.3.0
  - The IDE will now check MiniZinc code for syntax and type errors
  - The editor performs simple code completion for MiniZinc keywords
  - Ensure cursor is visible (editor scrolls to cursor position) when pressing
    tab or enter. Fixes #71.
  - Replace find dialog with inline widget and incremental search.
  - Support dark mode on macOS.
  - Add support for extra solver flags (parsed from solver configuration).
  - IDE now only uses minizinc executable (not mzn2fzn and solns2out).
  - Re-dock configuration editor when closing un-docked window.
  - Handle quotes when parsing additional solver command line arguments.
    Fixes #77.
  - Add workaround for the missing libnss requirements
  - Allow spaces in $DIR in MiniZincIDE.sh (Fixes #81)
2018-10-31
  v2.2.3
  - Only run solution checker if it is enabled in the solver configuration dialog.
2018-10-26
  v2.2.2
  - Add line/column display in status bar. Fixes #65.
  - Optional parameters don't have to be defined in input dialog.
  - Fix race condition in constructor of HTMLWindow. Fixes #64.
  - Provide mzn-json-init / mzn-json-init-end handlers to initialise HTML window
    before first solution is produced.
  - Add version information and minimum system version into Info.plist on macOS.
    Fixes #66.
  - Manage multiple open visualisation windows, and implement re-solve function
    that can be initiated from a visualisation.
2018-09-06
  v2.2.1
  - Improve dark mode by changing line numbers to dark background.
  - Make parameter input dialog scrollable.
  - Fix solution compression limit, and output one solution per
    block of compressed solutions.
2018-08-24
  v2.2.0
  - Update to MiniZinc 2.2.0.
  - Change solver configuration interface to work with new MiniZinc 2.2.0
    solver configurations.
  - Add support for solution checker models.
  - Better process management (to make sure solvers are terminated).
  - Change project files to be based on JSON format.
  - Better support for solver HTML output (used e.g. for Globalizer and FindMUS).
  - Fix shift left/shift right functionality.
  - Support for running models without saving them first.
  - Fix file dialogs to use correct file extensions.
2018-01-10
  v2.1.7
  - Update to MiniZinc 2.1.7.
  - Fix problem where files with a . in the filename could not be run (bug #44).
  - Fix font settings (were not saved reliably on some platforms).
  - Enable generic interface for submitting assignments (not just to Coursera).
  - Fix output handling for solvers that do not run mzn2fzn.
  - Fix hidden solution display when there are exactly as many solutions as the
    configured threshold for hiding solutions (bug #42).
  - Add configuration option to print timing information for each solution.
2017-09-22
  v2.1.6
  - Update to MiniZinc 2.1.6.
2017-05-17
  v2.1.5
  - Update to MiniZinc 2.1.5.
  - Fix an issue where solver output may not get printed if it occurs too
    quickly after the solver has started.
2017-03-16
  v2.1.4
  - Update to MiniZinc 2.1.4.
  - Fix major race condition that would crash the IDE when it didn't detect
    that a solver process had finished.
  - Improve HTML output by making sure every line is terminated by a newline.
2017-02-06
  v2.1.3
  - Update to MiniZinc 2.1.3.
  - Avoid crashes and print error messages when mzn2fzn subprocess crashes.
  - Changed meaning of "User-defined behavior" options, to have a clear
    distinction between optimisation and satisfaction problems.
  - Fix buffering of error output from mzn2fzn process (which would sometimes
    not be printed to the output window).
  - Suppress output after configurable number of solutions (to avoid
    overloading the IDE output box).
2016-12-20
  v2.1.2
  - Update to MiniZinc 2.1.2.
2016-12-14
  v2.1.1
  - Add option to print mzn2fzn statistics to project configuration.
  - Update to MiniZinc 2.1.1.
2016-11-16
  v2.1.0
  - Add new bundled solvers: Chuffed, CBC, Gurobi
  - Change update check to use Google Analytics (opt-in)
  - Fix a crash in the syntax highlighter when changing documents (e.g when
    saving a previously unsaved file).
  - Fix buffering problems on Windows (could lead to solver output not being
    shown).
  - Fix a crash when stopping a long-running compilation.
2016-08-30
  v2.0.97
  - Update to include MiniZinc 2.0.97 beta release.
2016-07-31
  v2.0.14
  - Implement new Coursera submission system.
  - Reload list of data files after removing a file through the project view,
    and use persistent indices to fix file removal. Fixes #11.
  - Fix renaming of files through the project explorer. Renaming should now
    work using the usual platform editing key, and using the context menu
    option. Fixes #12.
  - Don't add empty file name to list of data files when user cancels file
    dialog. Fixes #13.
  - Add same leading white space as on current line when pressing return
    (maintain indenting).
  - Add support for new Qt WebEngine framework (since Qt WebKit is not available
    in Qt 5.6).
2016-03-26
  v2.0.13
  - Flush output more consistently when process finished, hopefully
    fixing problem where solutions were missing from output.
  - Updated to include MiniZinc 2.0.13
2016-02-26
  v2.0.12
  - Fix link to MiniZinc issue tracker.
  - Add configuration option to clear solver output for each run.
  - Remember whether previous run used data file or manual data input.
  - Updated to include MiniZinc 2.0.12
2016-01-15
  v2.0.11
  - Updated to include MiniZinc 2.0.11
2015-12-10
  v2.0.10
  - Updated to include MiniZinc 2.0.10
2015-12-07
  v2.0.9
  - Remove (unimplemented) menu item for adding files to a project.
  - Fix version number comparison to work for multi-digit minor and patch
    versions.
2015-10-19
  v2.0.8
  - Only disable the run and compile actions when a solving process is currently
    running (keep editor and rest of the user interface enabled).
  - Keep editor font setting synchronised across different IDE windows.
2015-10-06
  v2.0.7
  - Changed version number scheme to coincide with MiniZinc version.
  - Disable all editing while the solver is running (avoids race conditions).
  - Fix behaviour of stop button: avoid race condition when pressing it twice,
    and signal that process has stopped when the initial SIGINT was successful.
  - Split up extra mzn2fzn command line arguments so they get passed correctly.
  - Changed behaviour of MiniZinc path input (now doesn't check for presence
    of mzn2fzn every time the cursor leaves the input box).
  - Add configuration option to use "default behaviour" when running models,
    which is to output all intermediate solutions for optimisation problems,
    and stop after one solution for satisfaction problems.
  - Fix "Add solver" dialog (sometimes the option to add solvers would
    disappear from the drop-down menu).
  - On Windows, configure Gecode/Gist to run the correct batch file.
  - Fix a crash when activating the (un)comment or go to line actions while
    on the configuration tab.
  - Avoid opening multiple "File modified" dialogs for the same file.
2015-07-30
  v0.9.9
  - Fix for clicking on error messages on Windows
  - Fix syntax highlighting, used to turn itself off when saving file
    under a different name
  - Set default font more consistently on different platforms
2015-07-01
  v0.9.8
  - Add "dark mode" to change text colours
  - Various bug fixes
  - Add integration with Coursera MiniZinc course
2015-05-12
  v0.9.7
  - Various bug fixes
  - Improved compatibility with MiniZinc 2.0.2
  - Bundled binary release (includes MiniZinc and some solvers)
2015-01-10
  v0.9.6
  - When killing a process (using the Stop action or timeout), send CTRL-C
    first, which allows the solver to exit gracefully. Solvers that do not
    react to CTRL-C are killed as before.
  - Fix copy/paste actions to also work in output window and to create
    rich text (including syntax colouring)
  - Avoid creating an empty .fzn file during compilation
  - Accept drag-and-drop to main window, opens dragged files
  - Quit menu action on Mac OS actually quits instead of just closing all
    open windows
  - Warn when loading large FlatZinc files
  - Assume UTF8 text encoding when loading and saving files
  - Keep selection of .dzn file in configuration tab when opening another
    .dzn file
2014-09-18
  v0.9.5
  - load new projects or files into existing project if it is empty
    and unmodified (avoids opening a new window)
  - fixed a bug when right-clicking into an empty area in the project
    explorer
  - fixed a bug when renaming files (in particular data files) in the
    project explorer
  - add support for multi-line (C-style) comments in the syntax
    highlighting
  - on Mac OS, show a Window menu to make it easy to switch between
    open projects, and open all files dragged onto the dock icon
    in the same project
  - fixed the hard-coded library path for the G12 lazyfd solver
  - fixed a bug that could cause a crash when closing and re-opening
    a project
2014-07-31
  v0.9.4
  - Project "drawer", better handling of projects
  - Tool bar
  - Limit additional arguments dialog to at most 10 parameters
  - Show MiniZinc version information in configuration dialog
  - More consistent handling of PATHs to MiniZinc and solvers
  - Print name of data files and additional arguments when running
    a solver
  - On Mac OS, enable QuickLook for MiniZinc files
  - Add recent files and projects to file menu
  - File dialogs open in the previously used directory
2014-04-01
  v0.9.3
  - Add elapsed time to output
  - Fix crash for files given as command line arguments
  - Make output window undockable
  - Add check for updates on startup
  - Fix bugs #4, #5, #8, #9
2014-02-03
  v0.9.2
  - Add verbose solver option
  - Save currently open project tab in project file
  - Ignore empty additional model parameters
  - Fix crash when closing modified Untitled tabs without saving
  - Fix crash after error message from solver
  - Fix project file format
  - Ask for parameter input when compiling (not just when solving)
2014-01-30
  v0.9.1
  Initial release


================================================
FILE: MiniZincIDE/MiniZincIDE.pri
================================================
QT       += core gui widgets websockets

VERSION = 2.9.7
DEFINES += MINIZINC_IDE_VERSION=\\\"$$VERSION\\\"

bundled {
    DEFINES += MINIZINC_IDE_BUNDLED
}

output_version {
    write_file($$OUT_PWD/version, VERSION)
}

!isEmpty(CXX_PREFIX) {
    message(Using CXX_PREFIX = $$CXX_PREFIX)
    QMAKE_CXX = $$CXX_PREFIX $$QMAKE_CXX
}

CONFIG += c++11

macx {
    ICON = $$PWD/mznide.icns
    OBJECTIVE_SOURCES += \
        $$PWD/darkmodenotifier_macos.mm
    LIBS += -framework Cocoa
    macx-xcode {
      QMAKE_INFO_PLIST = $$PWD/mznide-xcode.plist
    } else {
      QMAKE_INFO_PLIST = $$PWD/mznide-makefile.plist
    }
}

win32 {
    LIBS += -ladvapi32
}

RC_ICONS = $$PWD/mznide.ico

CONFIG += embed_manifest_exe

SOURCES += \
    $$PWD/codechecker.cpp \
    $$PWD/configwindow.cpp \
    $$PWD/darkmodenotifier.cpp \
    $$PWD/elapsedtimer.cpp \
    $$PWD/extraparamdialog.cpp \
    $$PWD/history.cpp \
    $$PWD/ide.cpp \
    $$PWD/ideutils.cpp \
    $$PWD/mainwindow.cpp \
    $$PWD/codeeditor.cpp \
    $$PWD/highlighter.cpp \
    $$PWD/fzndoc.cpp \
    $$PWD/outputwidget.cpp \
    $$PWD/preferencesdialog.cpp \
    $$PWD/process.cpp \
    $$PWD/profilecompilation.cpp \
    $$PWD/projectbrowser.cpp \
    $$PWD/server.cpp \
    $$PWD/gotolinedialog.cpp \
    $$PWD/paramdialog.cpp \
    $$PWD/outputdockwidget.cpp \
    $$PWD/checkupdatedialog.cpp \
    $$PWD/project.cpp \
    $$PWD/moocsubmission.cpp \
    $$PWD/esclineedit.cpp \
    $$PWD/solver.cpp \
    $$PWD/theme.cpp

HEADERS += \
    $$PWD/history.h \
    $$PWD/mainwindow.h \
    $$PWD/codechecker.h \
    $$PWD/codeeditor.h \
    $$PWD/configwindow.h \
    $$PWD/darkmodenotifier.h \
    $$PWD/elapsedtimer.h \
    $$PWD/exception.h \
    $$PWD/extraparamdialog.h \
    $$PWD/highlighter.h \
    $$PWD/fzndoc.h \
    $$PWD/ide.h \
    $$PWD/ideutils.h \
    $$PWD/outputwidget.h \
    $$PWD/preferencesdialog.h \
    $$PWD/process.h \
    $$PWD/profilecompilation.h \
    $$PWD/projectbrowser.h \
    $$PWD/server.h \
    $$PWD/gotolinedialog.h \
    $$PWD/paramdialog.h \
    $$PWD/outputdockwidget.h \
    $$PWD/checkupdatedialog.h \
    $$PWD/project.h \
    $$PWD/moocsubmission.h \
    $$PWD/esclineedit.h \
    $$PWD/solver.h \
    $$PWD/theme.h

FORMS += \
    $$PWD/configwindow.ui \
    $$PWD/extraparamdialog.ui \
    $$PWD/mainwindow.ui \
    $$PWD/outputwidget.ui \
    $$PWD/preferencesdialog.ui \
    $$PWD/projectbrowser.ui \
    $$PWD/gotolinedialog.ui \
    $$PWD/paramdialog.ui \
    $$PWD/checkupdatedialog.ui \
    $$PWD/moocsubmission.ui

RESOURCES += \
    $$PWD/minizincide.qrc

include($$PWD/../cp-profiler/cp-profiler.pri)
QT += network sql


================================================
FILE: MiniZincIDE/MiniZincIDE.pro
================================================
TARGET = MiniZincIDE
TEMPLATE = app

INCLUDEPATH += $$PWD/../

SOURCES += main.cpp

include($$PWD/MiniZincIDE.pri)

target.path = $$PREFIX/bin
INSTALLS += target


================================================
FILE: MiniZincIDE/README.txt
================================================
================================================================
MiniZinc IDE
================================================================

http://www.minizinc.org

The MiniZinc IDE is copyright 2013-2019 Monash University, NICTA, Data61/CSIRO.
Please see LICENSE.txt for license information.
Detailed installation instructions for Windows, Linux and macOS can be found
at https://www.minizinc.org/doc-latest/en/installation.html.


================================================
FILE: MiniZincIDE/cheat_sheet.mzn
================================================
                      %%%%%%%%%%%%%%%%%%%%%%%%
                      %                      %
                      % MiniZinc cheat sheet %
                      %                      %
                      %%%%%%%%%%%%%%%%%%%%%%%%

/******************
* Model structure *
******************/

include "globals.mzn";        % use globals library

int: n;                       % fixed integer parameter
var 1..n: x;                  % integer decision variable
array[1..n] of var 1..n: y;   % array of integer decision variables
constraint sum(y) <= x;       % constraint

solve satisfy;                % find satisfying solution

output ["Solution:\n", "x = ", show(x),  % output list of strings
        "y = \(y)"];                     % interpolation \(expression)

/***********************
* Basic types          *
***********************/

int: i;
3..5: j;                     % integer

float: f;
3.0..5.0: g;                 % floating point number

bool: b;                     % boolean

set of int: s;               % set
set of 3..5: t;

enum E = { Boat, Airplane }; % enumerated type

/***********************
* Type-insts           *
***********************/

var int: x;           % declare variable 
                      % (also with float, bool, and set of int)
var 3..7: y;          % declare variable with domain (also 3.0..7.0)
var set of 10..20: s; % declare set variable (only fixed set of int!)

array[1..4,1..10] of var 0.0..100.0: f;
                      % declare 2d array of float variables

var opt 1..10: ox;    % declare optional int variable (can be 1..10 or
                      % "absent", written <>)

/*********************
* Basic Constraints  *
*********************/
constraint x = y;
constraint x < y;
constraint x <= y;
constraint x > y;
constraint x >= y;
constraint x != y;    % not equals
   
/**********************
* Logical Connectives *
**********************/
                                   % conditionals
int: d = if i > 10 then a elseif i > 0 then b else c endif;
constraint if x < y then y < z else y > z endif;
   
constraint x < y \/ y != z;        % logical "or"
constraint x < y /\ y != z;        % logical "and"
constraint x < y -> y != z;        % logical implication
constraint not (x < y /\ y > z);   % logical negation

/******************
* Set Constraints *
******************/
   
constraint s subset t;             % non-strict subset relation
constraint s intersect t subset w; % intersection
constraint s union t subset w;     % union

/***************************
* Predicates and Functions *
***************************/
   
constraint all_different(x);       % predicate call
constraint mydiv(x,y) = 2;         % function call

/********************************
* Comprehensions and generators *
********************************/

array[int] of int: a = [ i | i in 1..10];
                      % create array [1,2,3,4,5,6,7,8,9,10]

array[int] of int: a = [ i | i in 1..10 where i mod 3=0];
                      % create array [3, 6, 9]

constraint forall (i,j in 1..n where i<j) (x[i] != x[j]);
                      % is the same as
constraint forall ([ x[i] != x[j] | i,j in 1..n where i<j ]);

/****************************
* Array index set coercions *
****************************/

array[20..30] of int: i = array1d(20..30, x);

array[int,int] of float: x =
  array2d(1..10, 1..10, [ 0.0 | i,j in 1..10 ]);

/********************************
* Search and search annotations *
********************************/

solve maximize sum(x);        % optimization
solve minimize sum(x);

solve ::int_search([x,y,z], input_order, indomain_min) satisfy;
                      % search annotation
                      % variable selection (examples):
                      %   input_order, first_fail, max_regret, smallest
                      % value selection (examples):
                      %   indomain_min, indomain_max, indomain,
                      %   indomain_split, indomain_reverse_split
                      % similar for bool_search, set_search, float_search

solve ::seq_search([int_search(x, first_fail, indomain),
                    int_search(y, input_order, indomain_min)])
      satisfy;
                      % first search x, then y



/*********************
* Strings and output *
**********************/

                      % concatenation using ++
                      % join arrays using string ", "
                      % convert expression into string using show
string: s = "a" ++ join(", ",[show(x[i]) | i in 1..3]);

/****************************************
* User-defined predicates and functions *
****************************************/

predicate no_overlap(var int: start0, var int: duration0,
                     var int: start1, var int: duration1) =
  start0 + duration0 <= start1 \/ start1 + duration1 <= start0;

function var float: average(array[int] of var int: x) =
  sum(x) / length(x);



================================================
FILE: MiniZincIDE/checkupdatedialog.cpp
================================================
#include "checkupdatedialog.h"
#include "ui_checkupdatedialog.h"

#include <QPushButton>

CheckUpdateDialog::CheckUpdateDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::CheckUpdateDialog)
{
    ui->setupUi(this);
}

CheckUpdateDialog::~CheckUpdateDialog()
{
    delete ui;
}


================================================
FILE: MiniZincIDE/checkupdatedialog.h
================================================
#ifndef CHECKUPDATEDIALOG_H
#define CHECKUPDATEDIALOG_H

#include <QDialog>

namespace Ui {
class CheckUpdateDialog;
}

class CheckUpdateDialog : public QDialog
{
    Q_OBJECT

public:
    explicit CheckUpdateDialog(QWidget *parent = 0);
    ~CheckUpdateDialog();
private:
    Ui::CheckUpdateDialog *ui;
};

#endif // CHECKUPDATEDIALOG_H


================================================
FILE: MiniZincIDE/checkupdatedialog.ui
================================================
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>CheckUpdateDialog</class>
 <widget class="QDialog" name="CheckUpdateDialog">
  <property name="windowModality">
   <enum>Qt::ApplicationModal</enum>
  </property>
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>480</width>
    <height>299</height>
   </rect>
  </property>
  <property name="sizePolicy">
   <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
    <horstretch>0</horstretch>
    <verstretch>0</verstretch>
   </sizepolicy>
  </property>
  <property name="minimumSize">
   <size>
    <width>387</width>
    <height>226</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>Automatic check for updates</string>
  </property>
  <property name="modal">
   <bool>true</bool>
  </property>
  <layout class="QHBoxLayout" name="horizontalLayout_3">
   <property name="sizeConstraint">
    <enum>QLayout::SetFixedSize</enum>
   </property>
   <item>
    <layout class="QHBoxLayout" name="horizontalLayout_2">
     <property name="sizeConstraint">
      <enum>QLayout::SetMaximumSize</enum>
     </property>
     <item>
      <layout class="QVBoxLayout" name="verticalLayout_2">
       <property name="sizeConstraint">
        <enum>QLayout::SetMinimumSize</enum>
       </property>
       <property name="topMargin">
        <number>4</number>
       </property>
       <item>
        <widget class="QLabel" name="label_3">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="minimumSize">
          <size>
           <width>100</width>
           <height>100</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>100</width>
           <height>100</height>
          </size>
         </property>
         <property name="text">
          <string/>
         </property>
         <property name="pixmap">
          <pixmap resource="minizincide.qrc">:/images/mznicon.png</pixmap>
         </property>
         <property name="scaledContents">
          <bool>true</bool>
         </property>
        </widget>
       </item>
       <item>
        <spacer name="verticalSpacer">
         <property name="orientation">
          <enum>Qt::Vertical</enum>
         </property>
         <property name="sizeHint" stdset="0">
          <size>
           <width>20</width>
           <height>40</height>
          </size>
         </property>
        </spacer>
       </item>
      </layout>
     </item>
     <item>
      <spacer name="horizontalSpacer_2">
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="sizeType">
        <enum>QSizePolicy::Preferred</enum>
       </property>
       <property name="sizeHint" stdset="0">
        <size>
         <width>10</width>
         <height>10</height>
        </size>
       </property>
      </spacer>
     </item>
     <item>
      <layout class="QVBoxLayout" name="verticalLayout">
       <property name="sizeConstraint">
        <enum>QLayout::SetMinimumSize</enum>
       </property>
       <property name="leftMargin">
        <number>0</number>
       </property>
       <property name="topMargin">
        <number>4</number>
       </property>
       <property name="rightMargin">
        <number>4</number>
       </property>
       <property name="bottomMargin">
        <number>4</number>
       </property>
       <item>
        <widget class="QLabel" name="label">
         <property name="sizePolicy">
          <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="text">
          <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The MiniZinc IDE can check automatically once a day whether any updates are available.&lt;/p&gt;&lt;p&gt;Please note that every update check sends anonymised statistics to Google Analytics. We only use these statistics to better understand our user base and to justify funding for further development!&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Do you want to enable the automatic update check?&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
         </property>
         <property name="wordWrap">
          <bool>true</bool>
         </property>
        </widget>
       </item>
       <item>
        <layout class="QHBoxLayout" name="horizontalLayout">
         <property name="sizeConstraint">
          <enum>QLayout::SetMinimumSize</enum>
         </property>
         <item>
          <spacer name="horizontalSpacer">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
           <property name="sizeHint" stdset="0">
            <size>
             <width>40</width>
             <height>20</height>
            </size>
           </property>
          </spacer>
         </item>
         <item>
          <widget class="QPushButton" name="nobutton">
           <property name="text">
            <string>No</string>
           </property>
          </widget>
         </item>
         <item>
          <widget class="QPushButton" name="yesbutton">
           <property name="text">
            <string>Yes</string>
           </property>
           <property name="default">
            <bool>true</bool>
           </property>
          </widget>
         </item>
        </layout>
       </item>
       <item>
        <widget class="QLabel" name="label_2">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
         <property name="text">
          <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;You can disable the update check at any time in the preferences dialog.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
         </property>
         <property name="wordWrap">
          <bool>true</bool>
         </property>
        </widget>
       </item>
      </layout>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <resources>
  <include location="minizincide.qrc"/>
 </resources>
 <connections>
  <connection>
   <sender>yesbutton</sender>
   <signal>clicked()</signal>
   <receiver>CheckUpdateDialog</receiver>
   <slot>accept()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>485</x>
     <y>215</y>
    </hint>
    <hint type="destinationlabel">
     <x>270</x>
     <y>119</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>nobutton</sender>
   <signal>clicked()</signal>
   <receiver>CheckUpdateDialog</receiver>
   <slot>reject()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>415</x>
     <y>215</y>
    </hint>
    <hint type="destinationlabel">
     <x>270</x>
     <y>119</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>


================================================
FILE: MiniZincIDE/codechecker.cpp
================================================
#include "codechecker.h"
#include "process.h"

CodeChecker::~CodeChecker()
{
    cancel();
}

void CodeChecker::connectSignals()
{
    connect(&p, &MznProcess::started, this, &CodeChecker::onStarted);
    connect(&p, &MznProcess::outputStdOut, this, &CodeChecker::onLine);
    connect(&p, &MznProcess::outputStdError, this, &CodeChecker::onLine);
    connect(&p, &MznProcess::finished, this, &CodeChecker::onFinished);
}

void CodeChecker::start(const QString& modelContents, SolverConfiguration& sc, const QString& wd)
{
    cancel();
    connectSignals();
    inRelevantError = false;
    curError = MiniZincError();
    mznErrors.clear();
    SolverConfiguration checkSc(sc.solverDefinition);
    checkSc.additionalData = sc.additionalData;
    checkSc.extraOptions = sc.extraOptions;
    QStringList args;
    args << "--model-check-only" << "-";
    input = modelContents;
    p.start(checkSc, args, wd);
}

void CodeChecker::cancel()
{
    p.disconnect();
    p.terminate();
}

void CodeChecker::onStarted()
{
    p.writeStdIn(input);
    p.closeStdIn();
}

void CodeChecker::onLine(const QString& l)
{
    QJsonParseError error;
    auto json = QJsonDocument::fromJson(l.toUtf8(), &error);
    if (json.isNull()) {
        return;
    }
    auto msg = json.object();
    if (msg["type"] != "error" && msg["type"] != "warning") {
        return;
    }
    if (!msg["location"].isObject()) {
        return;
    }
    auto loc = msg["location"].toObject();
    MiniZincError e;
    e.isWarning = msg["type"] == "warning";
    e.filename = loc["filename"].toString();
    e.first_line = loc["firstLine"].toInt();
    e.first_col = loc["firstColumn"].toInt();
    e.last_line = loc["lastLine"].toInt();
    e.last_col = loc["lastColumn"].toInt();
    e.msg = msg["message"].toString();
    if (e.filename == "stdin") {
        // Ignore errors that aren't from this file
        mznErrors.push_back(e);
    }
}

void CodeChecker::onFinished()
{
    emit finished(mznErrors);
}


================================================
FILE: MiniZincIDE/codechecker.h
================================================
#ifndef CHECKCODE_H
#define CHECKCODE_H

#include <QObject>

#include "codeeditor.h"
#include "process.h"

class CodeChecker : public QObject
{
    Q_OBJECT
public:
    explicit CodeChecker(QObject *parent = nullptr) : QObject(parent), p(this) {}
    ~CodeChecker();

    void start(const QString& modelContents, SolverConfiguration& sc, const QString& wd);
    void cancel(void);
signals:
    void finished(const QVector<MiniZincError>& mznErrors);

private slots:
    void onStarted(void);
    void onLine(const QString& data);
    void onFinished();

private:
    MznProcess p;
    QString input;

    bool inRelevantError = false;
    MiniZincError curError;
    QVector<MiniZincError> mznErrors;

    void connectSignals();
};

#endif // CHECKCODE_H


================================================
FILE: MiniZincIDE/codeeditor.cpp
================================================
/*
 *  Author:
 *     Guido Tack <guido.tack@monash.edu>
 *
 *  Copyright:
 *     NICTA 2013
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <QtWidgets>
#include "codeeditor.h"
#include "ide.h"
#include "mainwindow.h"

void
CodeEditor::initUI(QFont& font)
{
    setFont(font);
    QFontMetrics metrics(font);
    setTabStopDistance(metrics.horizontalAdvance(' ') * indentSize);

    lineNumbers= new LineNumbers(this);
    debugInfo = new DebugInfo(this);
    editorHeader = new EditorHeader(this);
    debugInfo->hide();
    connect(this, &QPlainTextEdit::blockCountChanged, this, &CodeEditor::setViewportWidth);
    connect(this, &QPlainTextEdit::updateRequest, this, &CodeEditor::setLineNumbers);
    connect(this, &QPlainTextEdit::updateRequest, this, &CodeEditor::setDebugInfoPos);
    connect(this, &QPlainTextEdit::cursorPositionChanged, this, &CodeEditor::cursorChange);
    connect(document(), &QTextDocument::modificationChanged, this, &CodeEditor::docChanged);
    connect(document(), &QTextDocument::contentsChanged, this, &CodeEditor::contentsChanged);

    setViewportWidth(0);
    cursorChange();

    highlighter = new Highlighter(font,theme,darkMode,document());
    setTheme(theme, darkMode);

    QTextCursor cursor(textCursor());
    cursor.movePosition(QTextCursor::Start);
    setTextCursor(cursor);
    ensureCursorVisible();
    setFocus();
}

CodeEditor::CodeEditor(QTextDocument* doc, const QString& path, bool isNewFile, bool large,
                       QFont& font, int indentSize0, bool useTabs0, const Theme& theme0, bool darkMode0,
                       QTabWidget* t, QWidget *parent) :
    QPlainTextEdit(parent), loadContentsButton(nullptr), tabs(t),
    indentSize(indentSize0), useTabs(useTabs0), theme(theme0), darkMode(darkMode0)
{
    if (doc) {
        QPlainTextEdit::setDocument(doc);
    }
    initUI(font);
    if (isNewFile) {
        filepath = "";
        filename = path;
    } else {
        filepath = QFileInfo(path).absoluteFilePath();
        filename = QFileInfo(path).fileName();
    }
    if (large) {
        setReadOnly(true);
        QPushButton* pb = new QPushButton("Big file. Load contents?", this);
        connect(pb, &QPushButton::clicked, this, &CodeEditor::loadContents);
        loadContentsButton = pb;
    }
    completer = new QCompleter(this);
    QStringList completionList;
    completionList << "annotation" << "array" << "bool" << "constraint"
                   << "diff" << "else" << "elseif" << "endif" << "enum" << "float"
                   << "function" << "include" << "intersect" << "maximize" << "minimize"
                   << "output" << "predicate" << "satisfy" << "solve" << "string"
                   << "subset" << "superset" << "symdiff" << "test" << "then"
                   << "union" << "where";
    completionList.sort();
    completionModel.setStringList(completionList);
    completer->setModel(&completionModel);
    completer->setCaseSensitivity(Qt::CaseSensitive);
    completer->setModelSorting(QCompleter::CaseSensitivelySortedModel);
    completer->setWrapAround(false);
    completer->setWidget(this);
    completer->setCompletionMode(QCompleter::PopupCompletion);
    QObject::connect(completer, QOverload<const QString&>::of(&QCompleter::activated), this, &CodeEditor::insertCompletion);

    modificationTimer.setSingleShot(true);
    QObject::connect(&modificationTimer, &QTimer::timeout, this, &CodeEditor::contentsChangedWithTimeout);

    auto* mw = qobject_cast<MainWindow*>(parent);
    if (mw != nullptr) {
        QObject::connect(this, &CodeEditor::escPressed, mw, &MainWindow::closeFindWidget);
    }

    setAcceptDrops(false);
    installEventFilter(this);
}

void CodeEditor::loadContents()
{
    static_cast<IDE*>(qApp)->loadLargeFile(filepath,this);
}

void CodeEditor::insertCompletion(const QString &completion)
{
    QTextCursor tc = textCursor();
    int extra = completion.length() - completer->completionPrefix().length();
    tc.movePosition(QTextCursor::Left);
    tc.movePosition(QTextCursor::EndOfWord);
    tc.insertText(completion.right(extra));
    setTextCursor(tc);
}

void CodeEditor::loadedLargeFile()
{
    setReadOnly(false);
    delete loadContentsButton;
    loadContentsButton = nullptr;
}

void CodeEditor::setDocument(QTextDocument *document)
{
    if (document) {
        delete highlighter;
        highlighter = nullptr;
    }
    disconnect(this, &QPlainTextEdit::blockCountChanged, this, &CodeEditor::setViewportWidth);
    disconnect(this, &QPlainTextEdit::updateRequest, this, &CodeEditor::setLineNumbers);
    disconnect(this, &QPlainTextEdit::updateRequest, this, &CodeEditor::setDebugInfoPos);
    disconnect(this, &QPlainTextEdit::cursorPositionChanged, this, &CodeEditor::cursorChange);
    disconnect(this->document(), &QTextDocument::modificationChanged, this, &CodeEditor::docChanged);
    QList<QTextEdit::ExtraSelection> noSelections;
    setExtraSelections(noSelections);
    QPlainTextEdit::setDocument(document);
    if (document) {
        QFont f= font();
        highlighter = new Highlighter(f, theme, darkMode, document);
    }
    connect(this, &QPlainTextEdit::blockCountChanged, this, &CodeEditor::setViewportWidth);
    connect(this, &QPlainTextEdit::updateRequest, this, &CodeEditor::setLineNumbers);
    connect(this, &QPlainTextEdit::updateRequest, this, &CodeEditor::setDebugInfoPos);
    connect(this, &QPlainTextEdit::cursorPositionChanged, this, &CodeEditor::cursorChange);
    connect(this->document(), &QTextDocument::modificationChanged, this, &CodeEditor::docChanged);
}

void CodeEditor::setTheme(const Theme& _theme, bool _darkMode)
{
    darkMode = _darkMode;
    theme = _theme;
    highlighter->setTheme(theme, darkMode);
    highlighter->rehighlight();

    auto palette = this->palette();
    palette.setColor(QPalette::Text, theme.textColor.get(darkMode));
    palette.setColor(QPalette::Base, theme.backgroundColor.get(darkMode));
    palette.setColor(QPalette::Highlight, theme.textHighlightColor.get(darkMode));
    palette.setColor(QPalette::HighlightedText, theme.textColor.get(darkMode));
    this->setPalette(palette);

    viewport()->setStyleSheet(theme.styleSheet(darkMode));
    cursorChange(); // Ensure extra selections are the correct colours
}

void CodeEditor::setIndentSize(int size)
{
    indentSize = size;
    QFontMetrics metrics(font());
    setTabStopDistance(metrics.horizontalAdvance(' ') * size);
}

Highlighter& CodeEditor::getHighlighter() {
    return *highlighter;
}

void CodeEditor::docChanged(bool c)
{
    int t = tabs == nullptr ? -1 : tabs->indexOf(this);
    if (t != -1) {
        QString title = tabs->tabText(t);
        title = title.mid(0, title.lastIndexOf(" *"));
        if (c)
            title += " *";
        tabs->setTabText(t,title);
    }
}

void CodeEditor::contentsChanged()
{
    modificationTimer.start(500);
}

void CodeEditor::contentsChangedWithTimeout()
{
    emit changedDebounced();
}

void CodeEditor::keyPressEvent(QKeyEvent *e)
{
    if (completer->popup()->isVisible()) {
        switch (e->key()) {
        case Qt::Key_Enter:
        case Qt::Key_Return:
        case Qt::Key_Escape:
        case Qt::Key_Tab:
        case Qt::Key_Backtab:
            e->ignore();
            return; // let the completer do default behavior
        default:
            break;
        }
    }
    if (e->key() == Qt::Key_Backtab) {
        e->accept();
        shiftLeft();
        ensureCursorVisible();
    } else if (e->key() == Qt::Key_Tab) {
        e->accept();
        auto cursor = textCursor();
        auto startBlock = document()->findBlock(cursor.selectionStart());
        auto endBlock = document()->findBlock(cursor.selectionEnd());
        auto partialLineSelection = startBlock.position() != cursor.selectionStart()
                || endBlock.position() + endBlock.length() - 1 != cursor.selectionEnd();
        if (!cursor.hasSelection() || (startBlock == endBlock && partialLineSelection)) {
            if (useTabs) {
                cursor.insertText("\t");
            } else {
                auto posInLine = cursor.selectionStart() - startBlock.position();
                auto distanceFromTabStop = 0;
                auto line = startBlock.text();
                for (int i = 0; i < posInLine; i++) {
                    if (line[i] == '\t') {
                        distanceFromTabStop = 0;
                    } else if (line[i].isSpace()) {
                        distanceFromTabStop++;
                    } else {
                        break;
                    }
                }
                auto toAdd = distanceFromTabStop % indentSize;
                if (toAdd == 0) {
                    toAdd = indentSize;
                }
                cursor.insertText(QString(" ").repeated(toAdd));
            }
        } else {
            shiftRight();
        }
        ensureCursorVisible();
    } else if (e->key() == Qt::Key_Return) {
        e->accept();
        QTextCursor cursor(textCursor());
        QString curLine = cursor.block().text();
        QRegularExpression leadingWhitespace("^(\\s*)");
        cursor.insertText("\n");
        auto leadingWhitespace_match = leadingWhitespace.match(curLine);
        if (leadingWhitespace_match.hasMatch()) {
            cursor.insertText(leadingWhitespace_match.captured(1));
        }
        ensureCursorVisible();
    } else if (e->key() == Qt::Key_Escape) {
        e->accept();
        emit escPressed();
    } else {
        bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E); // CTRL+E
        if (!isShortcut) // do not process the shortcut when we have a completer
            QPlainTextEdit::keyPressEvent(e);
        const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);
        if (ctrlOrShift && e->text().isEmpty())
            return;
        static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
        bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;

        QTextCursor tc = textCursor();
        tc.select(QTextCursor::WordUnderCursor);
        QString completionPrefix = tc.selectedText();
        if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3
                            || eow.contains(e->text().right(1)))) {
            completer->popup()->hide();
            return;
        }
        if (completionPrefix != completer->completionPrefix()) {
            completer->setCompletionPrefix(completionPrefix);
            completer->popup()->setCurrentIndex(completer->completionModel()->index(0, 0));
        }
        QRect cr = cursorRect();
        cr.setWidth(completer->popup()->sizeHintForColumn(0)
                    + completer->popup()->verticalScrollBar()->sizeHint().width());
        completer->complete(cr); // popup it up!
    }
}

int CodeEditor::lineNumbersWidth()
{
    int width = 1;
    int bc = blockCount();
    while (bc >= 10) {
        bc /= 10;
        ++width;
    }
    width = std::max(width,3);
    return 3 + fontMetrics().boundingRect(QLatin1Char('9')).width() * width;
}

int CodeEditor::debugInfoWidth()
{
    return !debugInfo->isVisible()?0:(3*DEBUG_TAB_SIZE);
}

int CodeEditor::debugInfoOffset()
{
    int heightOffset = 0;
    if(debugInfo->isVisible()){
        QFont lineNoFont = font();
        QFontMetrics fm(lineNoFont);
        heightOffset = fm.height();
    }
    return heightOffset;
}

void CodeEditor::showDebugInfo(bool show)
{
    if (filepath!="" && !filepath.endsWith(".mzn"))
        show = false;
    if (show) {
        if(debugInfo->isHidden()){
            debugInfo->show();
            setViewportWidth(0);
        }
    } else {
        if(!debugInfo->isHidden()){
            debugInfo->hide();
            setViewportWidth(0);
        }
    }
}

void CodeEditor::setViewportWidth(int)
{
    setViewportMargins(lineNumbersWidth(), debugInfoOffset(), debugInfoWidth(), 0);
}



void CodeEditor::setLineNumbers(const QRect &rect, int dy)
{
    if (dy)
        lineNumbers->scroll(0, dy);
    else
        lineNumbers->update(0, rect.y(), lineNumbers->width(), rect.height());

    if (rect.contains(viewport()->rect()))
        setViewportWidth(0);
}

void CodeEditor::setDebugInfoPos(const QRect &rect, int dy)
{
    if (dy)
        debugInfo->scroll(0, dy);
    else
        debugInfo->update(0, rect.y(), debugInfo->width(), rect.height());


    if (rect.contains(viewport()->rect()))
        setViewportWidth(0);
}





void CodeEditor::resizeEvent(QResizeEvent *e)
{
    QPlainTextEdit::resizeEvent(e);

    QRect cr = contentsRect();
    lineNumbers->setGeometry(QRect(cr.left(), cr.top()+debugInfoOffset(), lineNumbersWidth(), cr.height()));
    if (loadContentsButton) {
        loadContentsButton->move(cr.left()+lineNumbersWidth(), cr.top());
    }

    debugInfo->setGeometry(QRect(cr.right()-debugInfoWidth(), cr.top()+debugInfoOffset(), debugInfoWidth(), cr.height()));

    editorHeader->setGeometry(QRect(cr.left(), cr.top(), cr.width(), debugInfoOffset()));
}

void CodeEditor::showEvent(QShowEvent *event)
{
    setViewportWidth(0);
}



void CodeEditor::cursorChange()
{
    QList<QTextEdit::ExtraSelection> allExtraSels = extraSelections();

    BracketData* bd = static_cast<BracketData*>(textCursor().block().userData());
    QList<QTextEdit::ExtraSelection> extraSelections;

    {
        QTextEdit::ExtraSelection highlightLineSelection;
        QColor lineColor = theme.lineHighlightColor.get(darkMode);
        highlightLineSelection.format.setBackground(lineColor);
        highlightLineSelection.format.setProperty(QTextFormat::FullWidthSelection, true);
        highlightLineSelection.cursor = textCursor();
        highlightLineSelection.cursor.clearSelection();
        extraSelections.append(highlightLineSelection);
    }

    auto ec = theme.errorColor.get(darkMode);
    auto wc = theme.warningColor.get(darkMode);
    foreach (QTextEdit::ExtraSelection sel, allExtraSels) {
        if (sel.format.underlineColor() == ec || sel.format.underlineColor() == wc) {
            extraSelections.append(sel);
        }
    }

    if (bd) {
        QVector<Bracket>& brackets = bd->brackets;
        int pos = textCursor().block().position();
        for (int i=0; i<brackets.size(); i++) {
            int curPos = textCursor().position()-textCursor().block().position();
            Bracket& b = brackets[i];
            int parenPos0 = -1;
            int parenPos1 = -1;
            int errPos = -1;
            if (b.pos == curPos-1 && (b.b == '(' || b.b == '{' || b.b == '[')) {
                parenPos1 = matchLeft(textCursor().block(), b.b, i+1, 0);
                if (parenPos1 != -1) {
                    parenPos0 = pos+b.pos;
                } else {
                    errPos = pos+b.pos;
                }
            } else if (b.pos == curPos-1 && (b.b == ')' || b.b == '}' || b.b == ']')) {
                parenPos0 = matchRight(textCursor().block(), b.b, i-1, 0);
                if (parenPos0 != -1) {
                    parenPos1 = pos+b.pos;
                } else {
                    errPos = pos+b.pos;
                }
            }
            if (parenPos0 != -1 && parenPos1 != -1) {
                QTextEdit::ExtraSelection sel;
                QTextCharFormat format = sel.format;
                format.setBackground(theme.bracketsMatchColor.get(darkMode));
                sel.format = format;
                QTextCursor cursor = textCursor();
                cursor.setPosition(parenPos0);
                cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
                sel.cursor = cursor;
                extraSelections.append(sel);
                cursor.setPosition(parenPos1);
                cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
                sel.cursor = cursor;
                extraSelections.append(sel);
            }
            if (errPos != -1) {
                QTextEdit::ExtraSelection sel;
                QTextCharFormat format = sel.format;
                format.setBackground(theme.bracketsNoMatchColor.get(darkMode));
                sel.format = format;
                QTextCursor cursor = textCursor();
                cursor.setPosition(errPos);
                cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
                sel.cursor = cursor;
                extraSelections.append(sel);
            }
        }
    }

    setExtraSelections(extraSelections);
}

int CodeEditor::matchLeft(QTextBlock block, QChar b, int i, int nLeft)
{
    QChar match;
    switch (b.toLatin1()) {
    case '(' : match = ')'; break;
    case '{' : match = '}'; break;
    case '[' : match = ']'; break;
    default: break; // should not happen
    }

    while (block.isValid()) {
        BracketData* bd = static_cast<BracketData*>(block.userData());
        QVector<Bracket>& brackets = bd->brackets;
        int docPos = block.position();
        for (; i<brackets.size(); i++) {
            Bracket& b = brackets[i];
            if (b.b=='(' || b.b=='{' || b.b=='[') {
                nLeft++;
            } else if (b.b==match && nLeft==0) {
                return docPos+b.pos;
            } else {
                nLeft--;
            }
        }
        block = block.next();
        i = 0;
    }
    return -1;
}

int CodeEditor::matchRight(QTextBlock block, QChar b, int i, int nRight)
{
    QChar match;
    switch (b.toLatin1()) {
    case ')' : match = '('; break;
    case '}' : match = '{'; break;
    case ']' : match = '['; break;
    default: break; // should not happen
    }
    if (i==-1)
        block = block.previous();
    while (block.isValid()) {
        BracketData* bd = static_cast<BracketData*>(block.userData());
        QVector<Bracket>& brackets = bd->brackets;
        if (i==-1)
            i = brackets.size()-1;
        int docPos = block.position();
        for (; i>-1 && brackets.size()>0; i--) {
            Bracket& b = brackets[i];
            if (b.b==')' || b.b=='}' || b.b==']') {
                nRight++;
            } else if (b.b==match && nRight==0) {
                return docPos+b.pos;
            } else {
                nRight--;
            }
        }
        block = block.previous();
        i = -1;
    }
    return -1;
}

void CodeEditor::paintLineNumbers(QPaintEvent *event)
{
    QPainter painter(lineNumbers);
    QFont lineNoFont = font();
    QFontMetrics fm(lineNoFont);
    lineNoFont.setPointSizeF(lineNoFont.pointSizeF()*0.8);
    QFontMetrics fm2(lineNoFont);
    int ascentDiff = fontMetrics().ascent() - fm2.ascent();
    painter.setFont(lineNoFont);
    painter.fillRect(event->rect(), theme.lineNumberbackground.get(darkMode));

    QTextBlock block = firstVisibleBlock();
    int blockNumber = block.blockNumber();

    int top = static_cast<int>(blockBoundingGeometry(block).translated(contentOffset()).top());
    int bottom = top + static_cast<int>(blockBoundingRect(block).height());

//    painter.fillRect(event->rect(), QColor::fromRgb(QRandomGenerator::global()->generate()));

    int curLine = textCursor().blockNumber();

    while (block.isValid() && top <= event->rect().bottom()) {
        if (block.isVisible() && bottom >= event->rect().top()) {
            QString number = QString::number(blockNumber + 1);
            int textTop = top + ascentDiff;

            if (errorLines.contains(blockNumber)) {
                painter.setPen(theme.errorColor.get(darkMode));
            } else if (warningLines.contains(blockNumber)) {
                painter.setPen(theme.warningColor.get(darkMode));
            } else if (blockNumber == curLine) {
                painter.setPen(theme.foregroundActiveColor.get(darkMode));
            } else {
                painter.setPen(theme.foregroundInactiveColor.get(darkMode));
            }

            painter.drawText(0, textTop, lineNumbers->width(), fm2.height(),
                             Qt::AlignRight, number);
        }

        block = block.next();
        top = bottom;
        bottom = top + static_cast<int>(blockBoundingRect(block).height());
        ++blockNumber;
    }
}

QColor CodeEditor::interpolate(QColor start,QColor end,double ratio)
{
    //From https://stackoverflow.com/questions/3306786/get-intermediate-color-from-a-gradient
    int r = static_cast<int>(ratio*start.red() + (1-ratio)*end.red());
    int g = static_cast<int>(ratio*start.green() + (1-ratio)*end.green());
    int b = static_cast<int>(ratio*start.blue() + (1-ratio)*end.blue());
    int a = static_cast<int>(ratio*start.alpha() + (1-ratio)*end.alpha());
    QColor c = QColor::fromRgb(r,g,b);
    c.setAlpha(a); // Strangely there seems to be no clean way of creating a rgba color, fromRgba does not take 4 parameters as one would expect.
    return c;
}

QColor CodeEditor::heatColor(double ratio)
{
//return interpolate(darkMode?QColor(191, 0, 0):QColor(Qt::red).lighter(110), QColor(Qt::transparent), ratio);
//    QColor bg =  darkMode?QColor(0x26, 0x26, 0x26):Qt::white;
    QColor bg = theme.backgroundColor.get(darkMode);
    bg.setAlpha(50);
    return interpolate(darkMode?QColor(191, 0, 0):QColor(Qt::red).lighter(110), bg, ratio);
}

void CodeEditor::paintDebugInfo(QPaintEvent *event)
{
    QPainter painter(debugInfo);
    QFont lineNoFont = font();
    QFontMetrics fm(lineNoFont);
    int origFontHeight = fm.height();
    lineNoFont.setPointSizeF(lineNoFont.pointSizeF()*0.8);
    QFontMetrics fm2(lineNoFont);
    int heightDiff = (origFontHeight-fm2.height());
    painter.setFont(lineNoFont);

    painter.fillRect(event->rect(), theme.backgroundColor.get(darkMode));

    // TODO: This should be pre-computed only once and stored in each block.
    // Statistics should not be recounted at eack redraw...

    QTextBlock block = firstVisibleBlock();
    int blockNumber = block.blockNumber();
    int top = static_cast<int>(blockBoundingGeometry(block).translated(contentOffset()).top());
    int bottom = top + static_cast<int>(blockBoundingRect(block).height());

    int curLine = textCursor().blockNumber();

    painter.setPen(theme.foregroundActiveColor.get(darkMode));
    while (block.isValid() && top <= event->rect().bottom()) {
        BracketData* bd = static_cast<BracketData*>(block.userData());
        if (block.isVisible() && bottom >= event->rect().top() && bd->d.hasData()) {
//            int textTop = top+fontMetrics().leading()+heightDiff;
            int textTop = top+heightDiff;
            // num constraints
            painter.fillRect(0, top, DEBUG_TAB_SIZE, static_cast<int>(blockBoundingRect(block).height()),
                             heatColor(static_cast<double>(bd->d.con)/bd->d.totalCon));
            QString numConstraints = QString().number(bd->d.con);
            painter.drawText(0, textTop, DEBUG_TAB_SIZE, fm2.height(), Qt::AlignCenter, numConstraints);
            // num vars
            painter.fillRect(DEBUG_TAB_SIZE, top, DEBUG_TAB_SIZE, static_cast<int>(blockBoundingRect(block).height()),
                              heatColor(static_cast<double>(bd->d.var)/bd->d.totalVar));
            QString numVars = QString().number(bd->d.var);
            painter.drawText(DEBUG_TAB_SIZE, textTop, DEBUG_TAB_SIZE, fm2.height(), Qt::AlignCenter, numVars);
            // flatten time
            painter.fillRect(DEBUG_TAB_SIZE*2, top, DEBUG_TAB_SIZE, static_cast<int>(blockBoundingRect(block).height()),
                              heatColor(static_cast<double>(bd->d.ms)/bd->d.totalMs));
            QString flattenTime = QString().number(bd->d.ms);
            painter.drawText(DEBUG_TAB_SIZE*2, textTop, DEBUG_TAB_SIZE, fm2.height(), Qt::AlignCenter, flattenTime+"ms");
            //            painter.drawText(0, textTop, debugInfo->width(), fm2.height(),
//                             Qt::AlignLeft, number);
        }

        block = block.next();
        top = bottom;
        bottom = top + static_cast<int>(blockBoundingRect(block).height());
        ++blockNumber;
    }

    painter.setPen(theme.foregroundInactiveColor.get(darkMode));
    painter.drawLine(0,0,0,event->rect().bottom());
}

void CodeEditor::paintHeader(QPaintEvent *event)
{
    QPainter painter(editorHeader);
    QFont lineNoFont = font();
    QFontMetrics fm(lineNoFont);
    int origFontHeight = fm.height();
    lineNoFont.setPointSizeF(lineNoFont.pointSizeF()*0.8);
    QFontMetrics fm2(lineNoFont);
    int heightDiff = (origFontHeight-fm2.height());
    painter.setFont(lineNoFont);


    painter.fillRect(event->rect(), theme.backgroundColor.get(darkMode));
    int baseX = debugInfo->geometry().x();
    painter.setPen(theme.textColor.get(darkMode));
    painter.drawText(baseX, heightDiff/2, DEBUG_TAB_SIZE, debugInfoOffset(), Qt::AlignCenter, "Cons");
    painter.drawText(baseX + DEBUG_TAB_SIZE, heightDiff/2, DEBUG_TAB_SIZE, debugInfoOffset(), Qt::AlignCenter, "Vars");
    painter.drawText(baseX + DEBUG_TAB_SIZE*2, heightDiff/2, DEBUG_TAB_SIZE, debugInfoOffset(), Qt::AlignCenter, "Time");
}

void CodeEditor::setEditorFont(QFont& font)
{
    setFont(font);
    document()->setDefaultFont(font);
    highlighter->setEditorFont(font);
    setIndentSize(indentSize);
    highlighter->rehighlight();
}

bool CodeEditor::eventFilter(QObject *, QEvent *ev)
{
    if (ev->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(ev);
        if (keyEvent == QKeySequence::Copy) {
            copy();
            return true;
        } else if (keyEvent == QKeySequence::Cut) {
            cut();
            return true;
        }
    } else if (ev->type() == QEvent::ToolTip) {
        QHelpEvent* helpEvent = static_cast<QHelpEvent*>(ev);
        QPoint evPos = helpEvent->pos();
        evPos = QPoint(evPos.x()-lineNumbersWidth(),evPos.y());
        if (evPos.x() >= 0) {
            QTextCursor cursor = cursorForPosition(evPos);
            bool foundError = false;
            foreach (CodeEditorError cee, errors) {
                if (cursor.position() >= cee.startPos && cursor.position() <= cee.endPos) {
                    QToolTip::showText(helpEvent->globalPos(), cee.msg);
                    foundError = true;
                    break;
                }
            }
            if (!foundError) {
                cursor.select(QTextCursor::WordUnderCursor);
                QString loc(filename+":");
                loc += QString().number(cursor.block().blockNumber()+1);
                loc += ".";
                loc += QString().number(cursor.selectionStart()-cursor.block().position()+1);
                QHash<QString,QString>::iterator idMapIt = idMap.find(loc);
                if (idMapIt != idMap.end()) {
                    QToolTip::showText(helpEvent->globalPos(), idMapIt.value());
                } else {
                    QToolTip::hideText();
                }
            }
        } else {
            QToolTip::hideText();
        }
        return true;
    }
    return false;
}

void CodeEditor::copy()
{
    highlighter->copyHighlightedToClipboard(textCursor());
}


void CodeEditor::cut()
{
    highlighter->copyHighlightedToClipboard(textCursor());
    textCursor().removeSelectedText();
}

void CodeEditor::checkFile(const QVector<MiniZincError>& mznErrors)
{
    auto errorColor = theme.errorColor.get(darkMode);
    auto warningColor = theme.warningColor.get(darkMode);

    QList<QTextEdit::ExtraSelection> allExtraSels = extraSelections();

    QList<QTextEdit::ExtraSelection> extraSelections;
    foreach (QTextEdit::ExtraSelection sel, allExtraSels) {
        if (sel.format.underlineColor() != errorColor && sel.format.underlineColor() != warningColor) {
            extraSelections.append(sel);
        }
    }

    errors.clear();
    errorLines.clear();
    warningLines.clear();
    for (auto& it : mznErrors) {
        QTextEdit::ExtraSelection sel;
        QTextCharFormat format = sel.format;
        format.setUnderlineStyle(QTextCharFormat::WaveUnderline);
        format.setUnderlineColor(it.isWarning ? warningColor : errorColor);
        QTextBlock block = document()->findBlockByNumber(it.first_line-1);
        QTextBlock endblock = document()->findBlockByNumber(it.last_line-1);
        if (block.isValid() && endblock.isValid()) {
            QTextCursor cursor = textCursor();
            cursor.setPosition(block.position());
            int firstCol = it.first_col < it.last_col ? (it.first_col-1) : (it.last_col-1);
            int lastCol = it.first_col < it.last_col ? (it.last_col) : (it.first_col);
            cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, firstCol);
            int startPos = cursor.position();
            cursor.setPosition(endblock.position(), QTextCursor::KeepAnchor);
            cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, lastCol);
            int endPos = cursor.position();
            sel.cursor = cursor;
            sel.format = format;
            extraSelections.append(sel);
            CodeEditorError cee(startPos, endPos, QString(it.isWarning ? "Warning: %1" : "Error: %1").arg(it.msg));
            errors.append(cee);
            for (int j=it.first_line; j<=it.last_line; j++) {
                if (it.isWarning) {
                    warningLines.insert(j - 1);
                } else {
                    errorLines.insert(j - 1);
                }
            }
        }
    }
    setExtraSelections(extraSelections);
}

void CodeEditor::shiftLeft()
{
    shiftSelected(-1);
}

void CodeEditor::shiftRight()
{
    shiftSelected(1);
}

void CodeEditor::shiftSelected(int amount)
{
    auto origCursor = textCursor();
    origCursor.setKeepPositionOnInsert(true);
    QTextCursor cursor = textCursor();
    QTextBlock block = document()->findBlock(cursor.selectionStart());
    QTextBlock endblock = document()->findBlock(cursor.selectionEnd());
    bool atBlockStart = cursor.selectionEnd() == endblock.position();
    if (block==endblock || !atBlockStart)
        endblock = endblock.next();
    cursor.beginEditBlock();
    do {
        auto position = block.position();
        cursor.setPosition(position);
        auto indentation = 0;
        for (auto c : block.text()) {
            if (c == '\t') {
                indentation = indentSize * ((indentation + indentSize) / indentSize);
            } else if (c.isSpace()) {
                indentation++;
            } else {
                break;
            }
            position++;
        }
        cursor.setPosition(position, QTextCursor::KeepAnchor);
        auto newIndent = std::max(0, indentation + indentSize * amount);
        if (useTabs) {
            cursor.insertText(
                        QString("\t").repeated(newIndent / indentSize) +
                        QString(" ").repeated(newIndent % indentSize));
        } else {
            cursor.insertText(QString(" ").repeated(newIndent));
        }
        block = block.next();
    } while (block.isValid() && block != endblock);
    cursor.endEditBlock();
    origCursor.setKeepPositionOnInsert(false);
    setTextCursor(origCursor);
}


================================================
FILE: MiniZincIDE/codeeditor.h
================================================
/*
 *  Author:
 *     Guido Tack <guido.tack@monash.edu>
 *
 *  Copyright:
 *     NICTA 2013
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef CODEEDITOR_H
#define CODEEDITOR_H

#include <QPlainTextEdit>
#include <QTabWidget>
#include <QCompleter>
#include <QStringListModel>
#include <QTimer>

#include "highlighter.h"
#include "theme.h"

class CodeEditorError {
public:
    int startPos;
    int endPos;
    QString msg;
    CodeEditorError(int startPos0, int endPos0, const QString& msg0)
        : startPos(startPos0), endPos(endPos0), msg(msg0) {}
};

struct MiniZincError {
    bool isWarning;
    QString filename;
    int first_line;
    int last_line;
    int first_col;
    int last_col;
    QString msg;
};

class EditorHeader;

class CodeEditor : public QPlainTextEdit
{
    Q_OBJECT
public:
    explicit CodeEditor(QTextDocument* doc, const QString& path, bool isNewFile, bool large,
                        QFont& font, int indentSize, bool useTabs, const Theme& theme, bool darkMode,
                        QTabWidget* tabs, QWidget *parent);
    void paintLineNumbers(QPaintEvent *event);
    int lineNumbersWidth();
    void paintDebugInfo(QPaintEvent *event);
    void paintHeader(QPaintEvent *event);
    int debugInfoWidth();
    int debugInfoOffset();
    QString filepath;
    QString filename;
    QString playgroundTempFile;
    void setEditorFont(QFont& font);
    void setDocument(QTextDocument *document);
    void setTheme(const Theme& t, bool d);
    void setIndentSize(int size);
    void setIndentTab(bool useTabs0) { useTabs = useTabs0; }
    Highlighter& getHighlighter();
    void checkFile(const QVector<MiniZincError>& errors);
    void showDebugInfo(bool show);
    const static int DEBUG_TAB_SIZE = 70;
    void shiftLeft();
    void shiftRight();
protected:
    void resizeEvent(QResizeEvent *event);
    void showEvent(QShowEvent *event);
    void initUI(QFont& font);
    virtual void keyPressEvent(QKeyEvent *e);
    bool eventFilter(QObject *, QEvent *);
private slots:
    void setViewportWidth(int newBlockCount);
    void cursorChange();
    void setLineNumbers(const QRect &, int);
    void setDebugInfoPos(const QRect &, int);
    void docChanged(bool);
    void contentsChanged();
    void contentsChangedWithTimeout();
    void loadContents();
    void insertCompletion(const QString& completion);
private:
    QWidget* lineNumbers;
    QWidget* debugInfo;
    EditorHeader* editorHeader;
    QWidget* loadContentsButton;
    QTabWidget* tabs;
    Highlighter* highlighter;
    QCompleter* completer;
    QStringListModel completionModel;
    int indentSize;
    bool useTabs;
    QList<CodeEditorError> errors;
    QSet<int> errorLines;
    QSet<int> warningLines;
    QHash<QString,QString> idMap;
    QTimer modificationTimer;
    Theme theme;
    bool darkMode;
    int matchLeft(QTextBlock block, QChar b, int i, int n);
    int matchRight(QTextBlock block, QChar b, int i, int n);

    void shiftSelected(int amount);

    QColor interpolate(QColor start,QColor end,double ratio); // This should not go here
    QColor heatColor(double ratio); // This should not go here

signals:
    void escPressed();
    void changedDebounced();
public slots:
    void loadedLargeFile();
    void copy();
    void cut();
};

class LineNumbers: public QWidget
{
public:
    LineNumbers(CodeEditor *e) : QWidget(e), codeEditor(e) {}

    QSize sizeHint() const {
        return QSize(codeEditor->lineNumbersWidth(), 0);
    }

protected:
    void paintEvent(QPaintEvent *event) {
        codeEditor->paintLineNumbers(event);
    }

private:
    CodeEditor *codeEditor;
};

class DebugInfo: public QWidget
{
public:
    DebugInfo(CodeEditor *e) : QWidget(e), codeEditor(e) {}

    QSize sizeHint() const {
        return QSize(codeEditor->debugInfoWidth(), 0);
    }

protected:
    void paintEvent(QPaintEvent *event) {
        codeEditor->paintDebugInfo(event);
    }

private:
    CodeEditor *codeEditor;
};

class EditorHeader: public QWidget
{
    Q_OBJECT
public:
    EditorHeader(CodeEditor *e) : QWidget(e), codeEditor(e) {
        setMouseTracking(true);
    }

    QSize sizeHint() const {
        return QSize(0, codeEditor->debugInfoOffset());
    }

protected:
    void paintEvent(QPaintEvent *event) {
        codeEditor->paintHeader(event);
    }
private:
    CodeEditor *codeEditor;

};

#endif // CODEEDITOR_H


================================================
FILE: MiniZincIDE/configwindow.cpp
================================================
/*
 *  Main authors:
 *     Jason Nguyen <jason.nguyen@monash.edu>
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "configwindow.h"
#include "ui_configwindow.h"

#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include <QMessageBox>
#include <QMenu>
#include <QScrollBar>
#include <QValidator>
#include <QWidgetAction>

#include "process.h"
#include "exception.h"
#include "ideutils.h"

#include <algorithm>
#include <limits>
#include <cfloat>

ConfigWindow::ConfigWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ConfigWindow)
{
    ui->setupUi(this);
    ui->userDefinedBehavior_frame->setVisible(false);

    extraParamDialog = new ExtraParamDialog;

    auto* widgetAction = new QWidgetAction(nullptr);
    widgetAction->setDefaultWidget(extraParamDialog);

    auto* menu = new QMenu(this);
    menu->addAction(widgetAction);
    ui->addExtraParam_toolButton->setMenu(menu);

    connect(extraParamDialog, &ExtraParamDialog::addParams, this, [=](const QList<SolverFlag>& flags) {
        for (auto& f : flags) {
            addExtraParam(f);
            extraParamDialog->setParamEnabled(f, false);
        }
        resizeExtraFlagsTable();
        invalidate(false);
        menu->hide();
    });

    connect(extraParamDialog, &ExtraParamDialog::addCustomParam, this, [=]() {
        addExtraParam();
        resizeExtraFlagsTable();
        invalidate(false);
        menu->hide();
    });

    ui->extraParams_tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    ui->extraParams_tableWidget->setItemDelegateForColumn(3, new ExtraOptionDelegate);

    IDEUtils::watchChildChanges(ui->options_groupBox, this, std::bind(&ConfigWindow::invalidate, this, true));
    IDEUtils::watchChildChanges(ui->advanced_groupBox, this, std::bind(&ConfigWindow::invalidate, this, false));
}

ConfigWindow::~ConfigWindow()
{
    delete ui;
    for (auto sc : configs) {
        delete sc;
    }
}

void ConfigWindow::init()
{
    loadConfigs();
    initialized = true;
}

void ConfigWindow::loadConfigs(void)
{
    try {
        QStringList files;
        QStringList warnings;
        for (auto config : configs) {
            if (!config->paramFile.isEmpty()) {
                files.append(config->paramFile);
            }
            delete config;
        }
        configs.clear();
        for (auto* solver : MznDriver::get().solvers()) {
            if (solver->hasAllRequiredFlags()) {
                configs.append(new SolverConfiguration(*solver, true));
            }
        }
        if (!files.empty()) {
            for (auto fileName : files) {
                configs.append(new (SolverConfiguration) (SolverConfiguration::loadJSON(fileName, warnings)));
            }
        }
        populateComboBox();
        updateGUI(true);
        if (!warnings.empty()) {
            QMessageBox::warning(this, "MiniZinc IDE", warnings.join("\n"), QMessageBox::Ok);
        }
    } catch (Exception& e) {
        QMessageBox::warning(this, "Parameter configuration error", e.message(), QMessageBox::Ok);
    }
}

bool ConfigWindow::addConfig(const QString &fileName)
{
    int index = findConfigFile(fileName);
    if (index != -1) {
        // Already have this config
        setCurrentIndex(index);
        return true;
    }

    try {
        QStringList warnings;
        updateSolverConfig(configs[currentIndex()]);
        configs.append(new (SolverConfiguration) (SolverConfiguration::loadJSON(fileName, warnings)));
        for (auto sc : configs) {
            if (!sc->syncedOptionsMatch(*(configs.last()))) {
                populating = true; // Make sure this doesn't mark the config as modified
                ui->sync_checkBox->setChecked(false);
                populating = false;
                break;
            }
        }
        populateComboBox();

        if (ui->sync_checkBox->isChecked()) {
            // Ensure that newly loaded config overrides synced options
            populating = true; // Make sure this doesn't mark the config as modified
            ui->sync_checkBox->setChecked(false);
            populating = false;
            setCurrentIndex(configs.length() - 1);
            populating = true; // Make sure this doesn't mark the config as modified
            ui->sync_checkBox->setChecked(true);
            populating = false;
        }

        if (!warnings.empty()) {
            QMessageBox::warning(this, "MiniZinc IDE", warnings.join("\n"), QMessageBox::Ok);
        }

        return true;
    } catch (Exception& e) {
        QMessageBox::warning(this, "Parameter configuration error", e.message(), QMessageBox::Ok);
        return false;
    }
}

void ConfigWindow::mergeConfigs(const QList<SolverConfiguration*> confs)
{
    for (auto sc : confs) {
        int swapAt = sc->isBuiltin ?
                    findBuiltinConfig(sc->solverDefinition.id, sc->solverDefinition.version) :
                    findConfigFile(sc->paramFile);

        sc->modified = true;
        if (swapAt == -1) {
            sc->isBuiltin = false;
            configs.append(sc);
        } else {
            delete configs[swapAt];
            configs.replace(swapAt, sc);
        }
    }
    updateGUI(true);
    populateComboBox();
}

int ConfigWindow::findBuiltinConfig(const QString &id, const QString &version)
{
    int matchId = -1;
    int i = 0;
    for (auto sc : configs) {
        if (sc->isBuiltin && sc->solverDefinition.id == id) {
            matchId = i;
            if (sc->solverDefinition.version == version) {
                return i;
            }
        }
        i++;
    }
    return matchId;
}

int ConfigWindow::findConfigFile(const QString &file)
{
    if (file.isEmpty()) {
        // Unsaved configuration
        return -1;
    }
    int i = 0;
    for (auto sc : configs) {
        if (sc->paramFile == file) {
            return i;
        }
        i++;
    }
    return -1;
}

void ConfigWindow::stashModifiedConfigs()
{
    auto* selected = currentSolverConfig();
    for (auto* sc : configs) {
        if (sc->modified) {
            if (sc == selected) {
                stashSelectedModifiedConfig = stash.length();
            }
            stash.append(StashItem(sc));
        }
    }
    if (selected != nullptr) {
        if (selected->isBuiltin) {
            stashSelectedBuiltinSolverId = selected->solverDefinition.id;
            stashSelectedBuiltinSolverVersion = selected->solverDefinition.version;
        }
        stashSelectedParamFile = selected->paramFile;
    }
}

void ConfigWindow::unstashModifiedConfigs()
{
    lastIndex = -1;

    QList<SolverConfiguration*> merge;
    for (auto& item : stash) {
        try {
            merge.append(item.consume());
        }
        catch (...) {
            // Ignore
        }
    }
    mergeConfigs(merge);

    int i = -1;
    if (stashSelectedModifiedConfig >= 0 && stashSelectedModifiedConfig < merge.size()) {
        i = configs.indexOf(merge[stashSelectedModifiedConfig]);
    } else if (!stashSelectedParamFile.isEmpty()) {
        i = findConfigFile(stashSelectedParamFile);
    } else if (!stashSelectedBuiltinSolverId.isEmpty()) {
        i = findBuiltinConfig(stashSelectedBuiltinSolverId, stashSelectedBuiltinSolverVersion);
    }
    if (i != -1) {
        setCurrentIndex(i);
    }

    stash.clear();
    stashSelectedBuiltinSolverId = "";
    stashSelectedBuiltinSolverVersion = "";
    stashSelectedParamFile = "";
    stashSelectedModifiedConfig = -1;
}

QString ConfigWindow::saveConfig(int index)
{
    auto sc = configs[index];
    auto oldSc = sc;
    updateSolverConfig(configs[currentIndex()]);

    if (sc->isBuiltin) {
        // Must clone built-in configs
        sc = new SolverConfiguration(*sc);
    }

    QString target = sc->paramFile;
    if (sc->paramFile.isEmpty()) {
        QFileInfo fi(sc->paramFile);
        target = QFileDialog::getSaveFileName(this,
                                              "Save configuration",
                                              fi.canonicalFilePath(),
                                              "Solver configuration files (*.mpc)");
    }

    if (target.isEmpty()) {
        return "";
    }

    QFile f(target);
    f.open(QFile::WriteOnly | QFile::Truncate);
    f.write(sc->toJSON());
    f.close();

    oldSc->modified = false;
    sc->modified = false;
    sc->paramFile = target;
    populateComboBox();

    emit configSaved(target);
    return target;
}

QString ConfigWindow::saveConfig()
{
    return saveConfig(currentIndex());
}

SolverConfiguration* ConfigWindow::currentSolverConfig(void)
{
    int i = currentIndex();
    if (i < 0 || i >= configs.length()) {
        return nullptr;
    }
    auto sc = configs[i];
    updateSolverConfig(sc);
    return sc;
}

const QList<SolverConfiguration*>& ConfigWindow::solverConfigs()
{
    currentSolverConfig();
    return configs;
}

int ConfigWindow::currentIndex(void)
{
    return ui->config_comboBox->currentIndex();
}

void ConfigWindow::setCurrentIndex(int i)
{
    ui->config_comboBox->setCurrentIndex(qBound(0, i, configs.length()));
}

void ConfigWindow::on_numSolutions_checkBox_stateChanged(int arg1)
{
    ui->numSolutions_spinBox->setEnabled(arg1);
}

void ConfigWindow::on_numOptimal_checkBox_stateChanged(int arg1)
{
    ui->numOptimal_spinBox->setEnabled(arg1);
}

void ConfigWindow::on_timeLimit_checkBox_stateChanged(int arg1)
{
    ui->timeLimit_doubleSpinBox->setEnabled(arg1);
}

void ConfigWindow::on_randomSeed_checkBox_stateChanged(int arg1)
{
    ui->randomSeed_lineEdit->setEnabled(arg1);
}

void ConfigWindow::on_defaultBehavior_radioButton_toggled(bool checked)
{
    ui->defaultBehavior_frame->setVisible(checked);
}

void ConfigWindow::on_userDefinedBehavior_radioButton_toggled(bool checked)
{
    ui->userDefinedBehavior_frame->setVisible(checked);
}

void ConfigWindow::on_config_comboBox_currentIndexChanged(int index)
{
    if (!initialized) {
        return;
    }

    if (lastIndex >= 0) {
        updateSolverConfig(configs[lastIndex]);
    }

    lastIndex = index;

    updateGUI();

    if (index >= 0 && index < configs.length()) {
        emit selectedIndexChanged(index);
        emit selectedSolverConfigurationChanged(configs[index]);
    }
}

void ConfigWindow::updateGUI(bool overrideSync)
{
    int index = currentIndex();

    if (configs.isEmpty()) {
        ui->solver_controls->setVisible(false);
        ui->options_groupBox->setVisible(false);
        ui->advanced_groupBox->setVisible(false);
        return;
    }

    auto sc = configs[index];

    ui->solver_controls->setVisible(true);
    ui->options_groupBox->setVisible(true);
    ui->advanced_groupBox->setVisible(true);

    populating = true;

    ui->solver_label->setText(sc->solverDefinition.name + " " + sc->solverDefinition.version);

    ui->makeConfigDefault_pushButton->setEnabled(sc->isBuiltin && !sc->solverDefinition.isDefaultSolver);

    ui->reset_pushButton->setEnabled(sc->isBuiltin);

    ui->intermediateSolutions_checkBox->setEnabled(sc->supports("-a") || sc->supports("-i"));

    ui->numSolutions_checkBox->setEnabled(sc->supports("-a"));
    ui->numOptimal_checkBox->setEnabled(sc->supports("-a-o"));
    ui->verboseSolving_checkBox->setEnabled(sc->supports("-v"));
    ui->solvingStats_checkBox->setEnabled(sc->supports("-s"));

    if (overrideSync || !ui->sync_checkBox->isChecked()) {
        ui->timeLimit_checkBox->setChecked(sc->timeLimit != 0);
        ui->timeLimit_doubleSpinBox->setValue(sc->timeLimit / 1000.0);
        ui->timeLimit_doubleSpinBox->setEnabled(ui->timeLimit_checkBox->isChecked());

        if (sc->printIntermediate && sc->numSolutions == 1) {
            ui->defaultBehavior_radioButton->setChecked(true);
        } else {
            ui->userDefinedBehavior_radioButton->setChecked(true);
        }

        ui->intermediateSolutions_checkBox->setChecked(sc->printIntermediate);
        ui->numSolutions_spinBox->setValue(sc->numSolutions);
        ui->numSolutions_checkBox->setChecked(sc->numSolutions != 0);
        ui->numOptimal_spinBox->setValue(sc->numOptimal);
        ui->numOptimal_checkBox->setChecked(sc->numOptimal != 0);
        ui->verboseCompilation_checkBox->setChecked(sc->verboseCompilation);

        if (ui->verboseSolving_checkBox->isEnabled()) {
            ui->verboseSolving_checkBox->setChecked(sc->verboseSolving);
        }
        ui->compilationStats_checkBox->setChecked(sc->compilationStats);

        if (ui->solvingStats_checkBox->isEnabled()) {
            ui->solvingStats_checkBox->setChecked(sc->solvingStats);
        }

        ui->timingInfo_checkBox->setChecked(sc->outputTiming);
        ui->outputObjective_checkBox->setChecked(sc->outputObjective);
    }

    ui->outputObjective_checkBox->setEnabled(sc->solverDefinition.inputType != Solver::I_MZN || sc->supports("--output-objective"));

    ui->numSolutions_spinBox->setEnabled(ui->numSolutions_checkBox->isEnabled() && ui->numSolutions_checkBox->isChecked());
    ui->numOptimal_spinBox->setEnabled(ui->numOptimal_checkBox->isEnabled() && ui->numOptimal_checkBox->isChecked());

    ui->optimizationLevel_comboBox->setCurrentIndex(sc->optimizationLevel);
    ui->additionalData_plainTextEdit->setPlainText(sc->additionalData.join("\n"));

    ui->numThreads_spinBox->setEnabled(sc->supports("-p"));
    ui->numThreads_spinBox->setValue(sc->numThreads);

    bool enableRandomSeed = sc->supports("-r");
    ui->randomSeed_lineEdit->setText(sc->randomSeed.toString());
    ui->randomSeed_checkBox->setChecked(!sc->randomSeed.isNull());
    ui->randomSeed_checkBox->setEnabled(enableRandomSeed);
    ui->randomSeed_lineEdit->setEnabled(enableRandomSeed && !sc->randomSeed.isNull());

    bool enableFreeSearch = sc->supports("-f");
    ui->freeSearch_checkBox->setEnabled(enableFreeSearch);
    ui->freeSearch_checkBox->setChecked(sc->freeSearch);

    extraParamDialog->setParams(sc->solverDefinition.extraFlags);

    while (ui->extraParams_tableWidget->rowCount() > 0) {
        ui->extraParams_tableWidget->removeRow(0);
    }

    for (auto it = sc->extraOptions.begin(); it != sc->extraOptions.end(); it++) {
        bool matched = false;
        for (auto& f : sc->solverDefinition.extraFlags) {
            if (f.name == it.key()) {
                extraParamDialog->setParamEnabled(f, false);
                addExtraParam(f, it.value());
                matched = true;
                break;
            }
        }
        if (!matched) {
            addExtraParam(it.key(), false, it.value());
        }
    }

    for (auto it = sc->solverBackendOptions.begin(); it != sc->solverBackendOptions.end(); it++) {
        addExtraParam(it.key(), true, it.value());
    }

    resizeExtraFlagsTable();

    populating = false;
}


void ConfigWindow::updateSolverConfig(SolverConfiguration* sc)
{
    // Make sure if anything was being edited, we defocus to update the value
    auto* focus = focusWidget();
    if (focus && focus->hasFocus()) {
        focus->clearFocus();
        focus->setFocus();
    }

    if (!sc->modified) {
        return;
    }

    auto cfgs = ui->sync_checkBox->isChecked() ? configs : (QList<SolverConfiguration*>() << sc);
    for (auto s : cfgs) {
        s->timeLimit = ui->timeLimit_checkBox->isChecked() ? static_cast<int>(ui->timeLimit_doubleSpinBox->value() * 1000.0) : 0;
        if (ui->defaultBehavior_radioButton->isChecked()) {
            s->printIntermediate = true;
            s->numSolutions = 1;
            s->numOptimal = 1;
        } else {
            s->printIntermediate = ui->intermediateSolutions_checkBox->isChecked();
            s->numSolutions = ui->numSolutions_checkBox->isChecked() ? ui->numSolutions_spinBox->value() : 0;
            s->numOptimal = ui->numOptimal_checkBox->isChecked() ? ui->numOptimal_spinBox->value() : 0;
        }

        s->verboseCompilation = ui->verboseCompilation_checkBox->isChecked();
        s->verboseSolving = ui->verboseSolving_checkBox->isChecked();
        s->compilationStats = ui->compilationStats_checkBox->isChecked();
        s->solvingStats = ui->solvingStats_checkBox->isChecked();
        s->outputTiming = ui->timingInfo_checkBox->isChecked();
        s->outputObjective = ui->outputObjective_checkBox->isChecked();
    }

    sc->optimizationLevel = ui->optimizationLevel_comboBox->currentIndex();
    QString additionalData = ui->additionalData_plainTextEdit->toPlainText();
    sc->additionalData = additionalData.length() > 0 ? additionalData.split("\n") : QStringList();
    sc->numThreads = ui->numThreads_spinBox->value();
    sc->randomSeed = ui->randomSeed_checkBox->isChecked() ? ui->randomSeed_lineEdit->text() : QVariant();
    sc->freeSearch = ui->freeSearch_checkBox->isChecked();

    sc->extraOptions.clear();
    for (int row = 0; row < ui->extraParams_tableWidget->rowCount(); row++) {
        auto keyItem = ui->extraParams_tableWidget->item(row, 0);
        auto flagTypeWidget = static_cast<QComboBox*>(ui->extraParams_tableWidget->cellWidget(row, 1));
        auto valueItem = ui->extraParams_tableWidget->item(row, 3);
        if (keyItem && valueItem) {
            auto key = keyItem->data(Qt::UserRole).isNull() ?
                        keyItem->data(Qt::DisplayRole).toString() :
                        qvariant_cast<SolverFlag>(keyItem->data(Qt::UserRole)).name;
            auto value = valueItem->data(Qt::DisplayRole);
            if (flagTypeWidget && flagTypeWidget->currentIndex() == 1) {
                sc->solverBackendOptions.insert(key, value);
            } else {
                sc->extraOptions.insert(key, value);
            }
        }
    }
}

void ConfigWindow::on_removeExtraParam_toolButton_clicked()
{
    QVector<int> toBeRemoved;
    for (auto& range : ui->extraParams_tableWidget->selectedRanges()) {
        for (int i = range.topRow(); i <= range.bottomRow(); i++) {
            toBeRemoved.append(i);
        }
    }
    std::sort(toBeRemoved.begin(), toBeRemoved.end(), std::greater<int>());
    for (auto i : toBeRemoved) {
        auto data = ui->extraParams_tableWidget->item(i, 0)->data(Qt::UserRole);
        if (!data.isNull()) {
            // Re-enable adding of this flag
            extraParamDialog->setParamEnabled(qvariant_cast<SolverFlag>(data), true);
        }
        ui->extraParams_tableWidget->removeRow(i);
    }
    if (!toBeRemoved.isEmpty()) {
        resizeExtraFlagsTable();
        invalidate(false);
    }
}

void ConfigWindow::on_extraParams_tableWidget_itemSelectionChanged()
{
    bool hasSelection = ui->extraParams_tableWidget->selectedRanges().length();
    ui->removeExtraParam_toolButton->setEnabled(hasSelection);
}

void ConfigWindow::addExtraParam(const SolverFlag& f, const QVariant& value)
{
    int i = ui->extraParams_tableWidget->rowCount();
    ui->extraParams_tableWidget->insertRow(i);

    auto keyItem = new QTableWidgetItem(f.description);
    keyItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
    keyItem->setData(Qt::UserRole, QVariant::fromValue(f));
    keyItem->setToolTip(f.name);

    auto flagTypeItem = new QTableWidgetItem;
    flagTypeItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);

    auto typeItem = new QTableWidgetItem;
    typeItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);

    auto valueItem = new QTableWidgetItem;
    valueItem->setData(Qt::UserRole, QVariant::fromValue(f));
    if (value.isNull()) {
        valueItem->setData(Qt::DisplayRole, f.def);
    } else {
        valueItem->setData(Qt::DisplayRole, value);
    }
    if (f.t == SolverFlag::T_BOOL && f.def.toBool()) {
        // Non switched booleans which are default true cannot be turned off
        // TODO: Maybe this should send the flag when different to default?
        valueItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
    }

    ui->extraParams_tableWidget->setItem(i, 0, keyItem);
    ui->extraParams_tableWidget->setItem(i, 1, flagTypeItem);
    ui->extraParams_tableWidget->setItem(i, 2, typeItem);
    ui->extraParams_tableWidget->setItem(i, 3, valueItem);

    invalidate(false);
}

void ConfigWindow::addExtraParam(const QString& key, bool backend, const QVariant& value)
{
    int i = ui->extraParams_tableWidget->rowCount();
    ui->extraParams_tableWidget->insertRow(i);

    auto flag = key.startsWith("--") ? key.right(key.length() - 2) : key;
    auto keyItem = new QTableWidgetItem(flag);
    auto valItem = new QTableWidgetItem;
    valItem->setData(Qt::DisplayRole, value);
    ui->extraParams_tableWidget->setItem(i, 0, keyItem);
    ui->extraParams_tableWidget->setItem(i, 3, valItem);

    auto flagTypeComboBox = new QComboBox;
    flagTypeComboBox->addItems({"MiniZinc", "Solver backend"});
    flagTypeComboBox->setCurrentIndex(backend ? 1 : 0);
    flagTypeComboBox->setToolTip("Controls whether the flag is sent to the underlying solver executable (if available), or to the minizinc command.");
    ui->extraParams_tableWidget->setCellWidget(i, 1, flagTypeComboBox);

    auto typeComboBox = new QComboBox;
    typeComboBox->setToolTip("Controls the data type of the flag value");
    typeComboBox->addItems({"String", "Boolean", "Integer", "Float"});
    switch (value.type()) {
    case QVariant::String:
        typeComboBox->setCurrentIndex(0);
        break;
    case QVariant::Bool:
        typeComboBox->setCurrentIndex(1);
        break;
    case QVariant::Int:
        typeComboBox->setCurrentIndex(2);
        break;
    case QVariant::Double:
        typeComboBox->setCurrentIndex(3);
        break;
    default:
        typeComboBox->setCurrentIndex(0);
        break;
    }

    connect(typeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [=] (int typeIndex) mutable {
        QVariant::Type types[] = {QVariant::String, QVariant::Bool, QVariant::Int, QVariant::Double};
        auto target = types[typeIndex];
        auto data = valItem->data(Qt::DisplayRole);
        data.convert(target);
        auto newValItem = new QTableWidgetItem;
        newValItem->setData(Qt::DisplayRole, data);
        ui->extraParams_tableWidget->setItem(valItem->row(), 3, newValItem);
        valItem = newValItem;
    });

    ui->extraParams_tableWidget->setCellWidget(i, 2, typeComboBox);
}

void ConfigWindow::invalidate(bool all)
{
    if (populating) {
        // Ignore changes while populating the configuration widgets
        return;
    }

    bool refreshComboBox = false;

    int i = currentIndex();
    if (i >= 0 && i < configs.length() && !configs[i]->modified) {
        configs[i]->modified = true;
        refreshComboBox = true;
    }

    if (all && ui->sync_checkBox->isChecked()) {
        for (auto sc : configs) {
            // Only non-builtin configs really need to be saved after modifying basic options
            if (!sc->isBuiltin && !sc->modified) {
                sc->modified = true;
                refreshComboBox = true;
            }
        }
    }

    if (refreshComboBox) {
        populateComboBox();
    }
}

void ConfigWindow::populateComboBox()
{
    bool oldInitialized = initialized;
    int oldIndex = currentIndex();
    QStringList items;
    for (auto sc : configs) {
        items << sc->name();
    }

    initialized = false;
    ui->config_comboBox->clear();
    ui->config_comboBox->addItems(items);
    if (oldIndex >= 0 && oldIndex < configs.length()) {
        setCurrentIndex(oldIndex);
    } else {
        // Index no longer valid, just go back to default solver
        int i = 0;
        for (auto config : configs) {
            if (config->solverDefinition.isDefaultSolver) {
                setCurrentIndex(i);
                break;
            }
            i++;
        }
    }
    emit itemsChanged(items);
    initialized = oldInitialized;
}

void ConfigWindow::removeConfig(int i)
{
    bool targetIndex = i < currentIndex() ? currentIndex() - 1 : currentIndex();
    delete configs[i];
    configs.removeAt(i);
    populateComboBox();
    setCurrentIndex(targetIndex);
}

void ConfigWindow::on_clone_pushButton_clicked()
{
    auto sc = configs[currentIndex()];
    updateSolverConfig(sc);
    auto clone = new SolverConfiguration(*sc);
    clone->paramFile = "";
    clone->isBuiltin = false;
    clone->modified = true;
    configs << clone;
    populateComboBox();
    setCurrentIndex(configs.length() - 1);
}

void ConfigWindow::resizeExtraFlagsTable()
{
    auto* hScroll = ui->extraParams_tableWidget->horizontalScrollBar();
    // To avoid creating a vertical scrollbar if there's a horizontal one
    int padding = hScroll ? hScroll->height() : 0;
    int total_height = ui->extraParams_tableWidget->horizontalHeader()->height() + padding;
    if (!ui->extraParams_tableWidget->horizontalScrollBar()->isHidden()) {
        total_height += ui->extraParams_tableWidget->horizontalScrollBar()->height();
    }
    for (int row = 0; row < ui->extraParams_tableWidget->rowCount(); row++) {
        total_height += ui->extraParams_tableWidget->rowHeight(row);
    }
    ui->extraParams_tableWidget->setMinimumHeight(total_height);
}

QWidget* ExtraOptionDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    if (index.data(Qt::UserRole).canConvert<SolverFlag>()) {
        auto f = qvariant_cast<SolverFlag>(index.data(Qt::UserRole));
        switch (f.t) {
        case SolverFlag::T_INT:
        {
            auto field = new QLineEdit(parent);
            field->setAlignment(Qt::AlignRight);
            field->setValidator(new LongLongValidator());
            return field;
        }
        case SolverFlag::T_INT_RANGE:
        {
            if (f.min_ll < std::numeric_limits<int>::min() || f.max_ll > std::numeric_limits<int>::max()) {
                auto field = new QLineEdit(parent);
                field->setAlignment(Qt::AlignRight);
                field->setValidator(new LongLongValidator(f.min_ll, f.max_ll));
                return field;
            } else {
                auto field = new QSpinBox(parent);
                field->setRange(static_cast<int>(f.min_ll), static_cast<int>(f.max_ll));
                return field;
            }
        }
        case SolverFlag::T_FLOAT:
        {
            auto field = new QLineEdit(parent);
            field->setAlignment(Qt::AlignRight);
            field->setValidator(new QDoubleValidator());
            return field;
        }
        case SolverFlag::T_FLOAT_RANGE:
        {
            auto field = new QDoubleSpinBox(parent);
            field->setDecimals(DBL_MAX_10_EXP + DBL_DIG);
            field->setRange(f.min, f.max);
            return field;
        }
        case SolverFlag::T_OPT:
        {
            auto field = new QComboBox(parent);
            field->addItems(f.options);
            return field;
        }
        case SolverFlag::T_SOLVER:
        {
            auto field = new QComboBox(parent);
            for (auto* solver : MznDriver::get().solvers()) {
                field->addItem(solver->name);
            }
            return field;
        }
        case SolverFlag::T_BOOL:
        case SolverFlag::T_BOOL_ONOFF:
        case SolverFlag::T_STRING:
            return QStyledItemDelegate::createEditor(parent, option, index);
        }
    } else if (index.data().type() == QVariant::Double) {
        auto field = new QLineEdit(parent);
        field->setAlignment(Qt::AlignRight);
        field->setValidator(new QDoubleValidator());
        return field;
    } else {
        return QStyledItemDelegate::createEditor(parent, option, index);
    }
}

void ExtraOptionDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
    if (index.data(Qt::UserRole).canConvert<SolverFlag>()) {
        auto f = qvariant_cast<SolverFlag>(index.data(Qt::UserRole));
        switch (f.t) {
        case SolverFlag::T_INT:
            static_cast<QLineEdit*>(editor)->setText(QString::number(index.data().toLongLong()));
            break;
        case SolverFlag::T_INT_RANGE: {
            auto* e = qobject_cast<QSpinBox*>(editor);
            if (e) {
                e->setValue(index.data().toLongLong());
            } else {
                static_cast<QLineEdit*>(editor)->setText(QString::number(index.data().toLongLong()));
            }
            break;
        }
        case SolverFlag::T_FLOAT:
            static_cast<QLineEdit*>(editor)->setText(QString::number(index.data().toDouble()));
            break;
        case SolverFlag::T_FLOAT_RANGE:
            static_cast<QDoubleSpinBox*>(editor)->setValue(index.data().toDouble());
            break;
        case SolverFlag::T_OPT:
        case SolverFlag::T_SOLVER:
            static_cast<QComboBox*>(editor)->setCurrentText(index.data().toString());
            break;
        case SolverFlag::T_BOOL:
        case SolverFlag::T_BOOL_ONOFF:
        case SolverFlag::T_STRING:
            QStyledItemDelegate::setEditorData(editor, index);
            break;
        }
    } else if (index.data().type() == QVariant::Double) {
        static_cast<QLineEdit*>(editor)->setText(QString::number(index.data().toDouble()));
    } else {
        QStyledItemDelegate::setEditorData(editor, index);
    }
}

void ExtraOptionDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    if (index.data(Qt::UserRole).canConvert<SolverFlag>()) {
        auto f = qvariant_cast<SolverFlag>(index.data(Qt::UserRole));
        switch (f.t) {
        case SolverFlag::T_INT:
            model->setData(index, static_cast<QLineEdit*>(editor)->text().toInt());
            break;
        case SolverFlag::T_INT_RANGE: {
            auto* e = qobject_cast<QSpinBox*>(editor);
            if (e) {
                model->setData(index, e->value());
            } else {
                model->setData(index, static_cast<QLineEdit*>(editor)->text().toLongLong());
            }
            break;
        }
        case SolverFlag::T_BOOL:
        case SolverFlag::T_BOOL_ONOFF:
            QStyledItemDelegate::setModelData(editor, model, index);
            break;
        case SolverFlag::T_FLOAT:
            model->setData(index, static_cast<QLineEdit*>(editor)->text().toDouble());
            break;
        case SolverFlag::T_FLOAT_RANGE:
            model->setData(index, static_cast<QDoubleSpinBox*>(editor)->value());
            break;
        case SolverFlag::T_STRING:
            model->setData(index, static_cast<QLineEdit*>(editor)->text());
            break;
        case SolverFlag::T_OPT:
        case SolverFlag::T_SOLVER:
            model->setData(index, static_cast<QComboBox*>(editor)->currentText());
            break;
        }
    } else if (index.data().type() == QVariant::Double) {
        model->setData(index, static_cast<QLineEdit*>(editor)->text().toDouble());
    } else {
        QStyledItemDelegate::setModelData(editor, model, index);
    }
}

void ConfigWindow::on_makeConfigDefault_pushButton_clicked()
{
    auto sc = currentSolverConfig();
    if (!sc) {
        return;
    }
    try {
        MznDriver::get().setDefaultSolver(sc->solverDefinition);
        ui->makeConfigDefault_pushButton->setDisabled(true);
    } catch (Exception& e) {
        QMessageBox::warning(this, "MiniZinc IDE", e.message(), QMessageBox::Ok);
    }
}

void ConfigWindow::on_reset_pushButton_clicked()
{
    auto sc = currentSolverConfig();
    if (!sc || !sc->isBuiltin) {
        return;
    }

    auto* newSc = new SolverConfiguration(sc->solverDefinition, true);
    int i = currentIndex();
    delete configs[i];
    configs.replace(i, newSc);
    updateGUI(true);
    populateComboBox();
}

ConfigWindow::StashItem::StashItem(SolverConfiguration* sc) :
    json(sc->toJSONObject()),
    isBuiltIn(sc->isBuiltin),
    paramFile(sc->paramFile)
{}

SolverConfiguration* ConfigWindow::StashItem::consume() {
    QStringList warnings;
    auto* sc = new (SolverConfiguration) (SolverConfiguration::loadJSON(QJsonDocument(json), warnings));
    sc->isBuiltin = isBuiltIn;
    sc->paramFile = paramFile;
    return sc;
}


================================================
FILE: MiniZincIDE/configwindow.h
================================================
/*
 *  Main authors:
 *     Jason Nguyen <jason.nguyen@monash.edu>
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef CONFIGWINDOW_H
#define CONFIGWINDOW_H

#include <functional>

#include <QWidget>
#include <QVariant>
#include <QJsonDocument>
#include <QFormLayout>
#include <QMenu>
#include <QStyledItemDelegate>

#include "solver.h"
#include "extraparamdialog.h"

namespace Ui {
class ConfigWindow;
}

class ConfigWindow : public QWidget
{
    Q_OBJECT
    friend class TestIDE;

public:
    explicit ConfigWindow(QWidget *parent = nullptr);
    ~ConfigWindow();

    void init(void);

    ///
    /// \brief ConfigWindow::loadConfigs
    /// Loads or reloads solver configs, populating default solver configs, and reloading non-default configs
    ///
    void loadConfigs(void);

    ///
    /// \brief Loads a configuration from a JSON file
    /// \param fileName The path to the JSON file
    /// \return True if loading the config was successful
    ///
    bool addConfig(const QString& fileName);

    ///
    /// \brief Adds/merges in existing solver configurations
    /// \param configs The configurations to add
    ///
    void mergeConfigs(const QList<SolverConfiguration*> configs);

    int findBuiltinConfig(const QString& id, const QString& version);
    int findConfigFile(const QString& file);

    void removeConfig(int i);

    ///
    /// \brief Stash modified configs so they can be re-added later
    /// Stash modified configs and record the currently selected one
    ///
    void stashModifiedConfigs();

    ///
    /// \brief Unstash previously stashed modified configs
    /// Unstash modified configs and select the config that was active during stashing
    ///
    void unstashModifiedConfigs();

    ///
    /// \brief Saves the solver configuration with the given index
    /// \param index The index of the solver configuration to save
    /// \return The location of the saved file or empty if cancelled
    ///
    QString saveConfig(int index);

    ///
    /// \brief Saves the currently solver configuration
    /// \return The location of the saved file or empty if cancelled
    ///
    QString saveConfig(void);

    ///
    /// \brief Gets the index of the current solver configuration
    /// \return The current solver configuration index
    ///
    int currentIndex(void);

    ///
    /// \brief Sets the current solver configuration index
    /// \param i The new solver configuration index
    ///
    void setCurrentIndex(int i);

    ///
    /// \brief Gets the active solver configuration
    /// \return The current solver config or nullptr
    ///
    SolverConfiguration* currentSolverConfig(void);

    ///
    /// \brief Gets a list of all loaded solver configurations
    /// \return A list of solver configurations
    ///
    const QList<SolverConfiguration*>& solverConfigs(void);
signals:
    void selectedIndexChanged(int index);
    void selectedSolverConfigurationChanged(const SolverConfiguration* sc);
    void itemsChanged(const QStringList& items);
    void configSaved(const QString& filename);

private slots:
    void on_numSolutions_checkBox_stateChanged(int arg1);

    void on_timeLimit_checkBox_stateChanged(int arg1);

    void on_randomSeed_checkBox_stateChanged(int arg1);

    void on_defaultBehavior_radioButton_toggled(bool checked);

    void on_userDefinedBehavior_radioButton_toggled(bool checked);

    void on_config_comboBox_currentIndexChanged(int index);

    void on_removeExtraParam_toolButton_clicked();

    void on_extraParams_tableWidget_itemSelectionChanged();

    void on_numOptimal_checkBox_stateChanged(int arg1);

    void on_clone_pushButton_clicked();

    void on_makeConfigDefault_pushButton_clicked();

    void on_reset_pushButton_clicked();

private:
    class StashItem {
    public:
        StashItem() {}
        StashItem(SolverConfiguration* sc);
        SolverConfiguration* consume();
    private:
        QJsonObject json;
        bool isBuiltIn;
        QString paramFile;
    };

    Ui::ConfigWindow *ui;

    QList<SolverConfiguration*> configs;

    QVector<StashItem> stash;
    QString stashSelectedBuiltinSolverId;
    QString stashSelectedBuiltinSolverVersion;
    QString stashSelectedParamFile;
    int stashSelectedModifiedConfig = -1;

    int lastIndex = -1;
    bool initialized = false;
    bool populating = false;

    void updateGUI(bool overrideSync = false);
    void updateSolverConfig(SolverConfiguration* sc);
    void addExtraParam(const QString& key = "", bool backend = false, const QVariant& value = "");
    void addExtraParam(const SolverFlag& f, const QVariant& value = QVariant());
    void invalidate(bool all);
    void populateComboBox(void);
    void resizeExtraFlagsTable(void);

    ExtraParamDialog* extraParamDialog;
};

class ExtraOptionDelegate : public QStyledItemDelegate {
    Q_OBJECT
public:
    using QStyledItemDelegate::QStyledItemDelegate;

    QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
    void setEditorData(QWidget* editor, const QModelIndex& index) const override;
    void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
};

class LongLongValidator : public QValidator {
    Q_OBJECT
public:
    LongLongValidator(qlonglong min, qlonglong max, QObject *parent = nullptr)
        : QValidator(parent), _min(min), _max(max) {}
    LongLongValidator(QObject *parent = nullptr) : QValidator(parent) {}
    qlonglong bottom() const { return _min; }
    qlonglong top() const { return _max; }
    void setBottom(qlonglong min){
        if (_min != min) {
            _min = min;
            changed();
        }
    }
    void setTop(qlonglong max){
        if (_max != max) {
            _max = max;
            changed();
        }
    }
    void setRange(qlonglong min, qlonglong max){
        setBottom(min);
        setTop(max);
    }
    QValidator::State validate(QString &input, int&) const override{
        bool ok = false;
        qlonglong n = input.toLongLong(&ok);
        if (!ok) {
            return QValidator::Invalid;
        }
        if (n < _min || n > _max) {
            return QValidator::Intermediate;
        }
        return QValidator::Acceptable;
    }
private:
    qlonglong _min = std::numeric_limits<qlonglong>::min();
    qlonglong _max = std::numeric_limits<qlonglong>::max();
};



#endif // CONFIGWINDOW_H


================================================
FILE: MiniZincIDE/configwindow.ui
================================================
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>ConfigWindow</class>
 <widget class="QWidget" name="ConfigWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>688</width>
    <height>1140</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout_5">
   <item>
    <layout class="QVBoxLayout" name="verticalLayout">
     <item>
      <widget class="QGroupBox" name="config_groupBox">
       <property name="title">
        <string>Configuration</string>
       </property>
       <layout class="QVBoxLayout" name="verticalLayout_2">
        <property name="leftMargin">
         <number>0</number>
        </property>
        <property name="topMargin">
         <number>0</number>
        </property>
        <property name="rightMargin">
         <number>0</number>
        </property>
        <property name="bottomMargin">
         <number>0</number>
        </property>
        <item>
         <widget class="QWidget" name="solver_controls" native="true">
          <layout class="QHBoxLayout" name="horizontalLayout_9">
           <item>
            <layout class="QGridLayout" name="gridLayout_4">
             <item row="0" column="0">
              <widget class="QComboBox" name="config_comboBox">
               <property name="sizePolicy">
                <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
                 <horstretch>0</horstretch>
                 <verstretch>0</verstretch>
                </sizepolicy>
               </property>
               <property name="toolTip">
                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The currently selected solver configuration&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
               </property>
              </widget>
             </item>
             <item row="0" column="1">
              <layout class="QHBoxLayout" name="horizontalLayout_4">
               <item>
                <widget class="QPushButton" name="clone_pushButton">
                 <property name="text">
                  <string>Clone</string>
                 </property>
                </widget>
               </item>
               <item>
                <widget class="QPushButton" name="makeConfigDefault_pushButton">
                 <property name="toolTip">
                  <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Make this solver configuration the default.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
                 </property>
                 <property name="text">
                  <string>Set as default</string>
                 </property>
                </widget>
               </item>
              </layout>
             </item>
             <item row="1" column="0" colspan="2">
              <layout class="QHBoxLayout" name="horizontalLayout">
               <item>
                <widget class="QLabel" name="label_4">
                 <property name="text">
                  <string>Solver:</string>
                 </property>
                </widget>
               </item>
               <item>
                <widget class="QLabel" name="solver_label">
                 <property name="text">
                  <string>&lt;unknown&gt;</string>
                 </property>
                </widget>
               </item>
               <item>
                <spacer name="horizontalSpacer">
                 <property name="orientation">
                  <enum>Qt::Horizontal</enum>
                 </property>
                 <property name="sizeHint" stdset="0">
                  <size>
                   <width>40</width>
                   <height>20</height>
                  </size>
                 </property>
                </spacer>
               </item>
               <item>
                <widget class="QPushButton" name="reset_pushButton">
                 <property name="text">
                  <string>Reset to defaults</string>
                 </property>
                </widget>
               </item>
              </layout>
             </item>
            </layout>
           </item>
          </layout>
         </widget>
        </item>
       </layout>
      </widget>
     </item>
     <item>
      <widget class="QGroupBox" name="options_groupBox">
       <property name="title">
        <string>Options</string>
       </property>
       <layout class="QVBoxLayout" name="verticalLayout_4">
        <item>
         <widget class="QCheckBox" name="sync_checkBox">
          <property name="toolTip">
           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Preserve these options when switching solver configurations.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
          </property>
          <property name="text">
           <string>Maintain these options across solver configurations</string>
          </property>
          <property name="checked">
           <bool>true</bool>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QGroupBox" name="solving_groupBox">
          <property name="title">
           <string>Solving</string>
          </property>
          <layout class="QVBoxLayout" name="verticalLayout_9">
           <item>
            <layout class="QHBoxLayout" name="horizontalLayout_7">
             <item>
              <widget class="QCheckBox" name="timeLimit_checkBox">
               <property name="toolTip">
                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Limit running time to the given amount in seconds.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
               </property>
               <property name="text">
                <string>Time limit:</string>
               </property>
              </widget>
             </item>
             <item>
              <widget class="QDoubleSpinBox" name="timeLimit_doubleSpinBox">
               <property name="enabled">
                <bool>false</bool>
               </property>
               <property name="sizePolicy">
                <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
                 <horstretch>0</horstretch>
                 <verstretch>0</verstretch>
                </sizepolicy>
               </property>
               <property name="alignment">
                <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
               </property>
               <property name="suffix">
                <string>s</string>
               </property>
               <property name="decimals">
                <number>3</number>
               </property>
               <property name="maximum">
                <double>99999.998999999996158</double>
               </property>
              </widget>
             </item>
            </layout>
           </item>
           <item>
            <layout class="QHBoxLayout" name="horizontalLayout_8">
             <item>
              <widget class="QRadioButton" name="defaultBehavior_radioButton">
               <property name="text">
                <string>Default behavior</string>
               </property>
               <property name="checked">
                <bool>true</bool>
               </property>
              </widget>
             </item>
             <item>
              <widget class="QRadioButton" name="userDefinedBehavior_radioButton">
               <property name="text">
                <string>User defined behavior</string>
               </property>
              </widget>
             </item>
            </layout>
           </item>
           <item>
            <widget class="QFrame" name="defaultBehavior_frame">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
             <property name="frameShape">
              <enum>QFrame::Panel</enum>
             </property>
             <property name="frameShadow">
              <enum>QFrame::Raised</enum>
             </property>
             <layout class="QGridLayout" name="gridLayout_6">
              <item row="0" column="0">
               <widget class="QLabel" name="label_7">
                <property name="text">
                 <string>Optimization problems:</string>
                </property>
               </widget>
              </item>
              <item row="0" column="1">
               <widget class="QLabel" name="label_16">
                <property name="enabled">
                 <bool>false</bool>
                </property>
                <property name="sizePolicy">
                 <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
                  <horstretch>0</horstretch>
                  <verstretch>0</verstretch>
                 </sizepolicy>
                </property>
                <property name="text">
                 <string>print all intermediate solutions</string>
                </property>
               </widget>
              </item>
              <item row="1" column="0">
               <widget class="QLabel" name="label_12">
                <property name="text">
                 <string>Satisfaction problems: </string>
                </property>
               </widget>
              </item>
              <item row="1" column="1">
               <widget class="QLabel" name="label_17">
                <property name="enabled">
                 <bool>false</bool>
                </property>
                <property name="sizePolicy">
                 <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
                  <horstretch>0</horstretch>
                  <verstretch>0</verstretch>
                 </sizepolicy>
                </property>
                <property name="text">
                 <string>stop after first solution</string>
                </property>
               </widget>
              </item>
             </layout>
            </widget>
           </item>
           <item>
            <widget class="QFrame" name="userDefinedBehavior_frame">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
             </property>
             <property name="frameShape">
              <enum>QFrame::Panel</enum>
             </property>
             <property name="frameShadow">
              <enum>QFrame::Raised</enum>
             </property>
             <layout class="QVBoxLayout" name="verticalLayout_6">
              <item>
               <widget class="QGroupBox" name="groupBox">
                <property name="title">
                 <string>Optimization problems</string>
                </property>
                <layout class="QVBoxLayout" name="verticalLayout_7">
                 <item>
                  <widget class="QCheckBox" name="intermediateSolutions_checkBox">
                   <property name="toolTip">
                    <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Print intermediate solutions with &lt;span style=&quot; font-family:'monospace';&quot;&gt;-i&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
                   </property>
                   <property name="text">
                    <string>Print intermediate solutions</string>
                   </property>
                   <property name="checked">
                    <bool>true</bool>
                   </property>
                  </widget>
                 </item>
                 <item>
                  <widget class="QCheckBox" name="numOptimal_checkBox">
                   <property name="toolTip">
                    <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Limit number of optimal  solutions with &lt;span style=&quot; font-family:'monospace';&quot;&gt;-n-o&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
                   </property>
                   <property name="text">
                    <string>Stop after this many optimal solutions (uncheck for all)</string>
                   </property>
                   <property name="checked">
                    <bool>true</bool>
                   </property>
                  </widget>
                 </item>
                 <item>
                  <widget class="QSpinBox" name="numOptimal_spinBox">
                   <property name="sizePolicy">
                    <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
                     <horstretch>0</horstretch>
                     <verstretch>0</verstretch>
                    </sizepolicy>
                   </property>
                   <property name="minimum">
                    <number>1</number>
                   </property>
                  </widget>
                 </item>
                </layout>
               </widget>
              </item>
              <item>
               <widget class="QGroupBox" name="groupBox_2">
                <property name="title">
                 <string>Satisfaction problems</string>
                </property>
                <layout class="QVBoxLayout" name="verticalLayout_8">
                 <item>
                  <widget class="QCheckBox" name="numSolutions_checkBox">
                   <property name="toolTip">
                    <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Limit number of solutions with &lt;span style=&quot; font-family:'monospace';&quot;&gt;-n&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
                   </property>
                   <property name="text">
                    <string>Stop after this many solutions (uncheck for all)</string>
                   </property>
                   <property name="checked">
                    <bool>true</bool>
                   </property>
                  </widget>
                 </item>
                 <item>
                  <widget class="QSpinBox" name="numSolutions_spinBox">
                   <property name="sizePolicy">
                    <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
                     <horstretch>0</horstretch>
                     <verstretch>0</verstretch>
                    </sizepolicy>
                   </property>
                   <property name="minimum">
                    <number>1</number>
                   </property>
                   <property name="maximum">
                    <number>999999</number>
                   </property>
                   <property name="value">
                    <number>1</number>
                   </property>
                  </widget>
                 </item>
                </layout>
               </widget>
              </item>
             </layout>
            </widget>
           </item>
          </layout>
         </widget>
        </item>
        <item>
         <widget class="QGroupBox" name="output_groupBox">
          <property name="title">
           <string>Output</string>
          </property>
          <layout class="QHBoxLayout" name="horizontalLayout_3">
           <item>
            <layout class="QGridLayout" name="gridLayout">
             <item row="0" column="0">
              <widget class="QCheckBox" name="verboseCompilation_checkBox">
               <property name="toolTip">
                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable verbose compilation with &lt;span style=&quot; font-family:'monospace';&quot;&gt;--verbose-compilation&lt;/span&gt;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
               </property>
               <property name="text">
                <string>Verbose compilation</string>
               </property>
              </widget>
             </item>
             <item row="2" column="1">
              <widget class="QCheckBox" name="solvingStats_checkBox">
               <property name="toolTip">
                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Output solving statistics with &lt;span style=&quot; font-family:'monospace';&quot;&gt;--solver-statistics&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
               </property>
               <property name="text">
                <string>Output solving statistics</string>
               </property>
              </widget>
             </item>
             <item row="0" column="1">
              <widget class="QCheckBox" name="verboseSolving_checkBox">
               <property name="toolTip">
                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable verbose compilation with &lt;span style=&quot; font-family:'monospace';&quot;&gt;--verbose-solving&lt;/span&gt;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
               </property>
               <property name="text">
                <string>Verbose Solving</string>
               </property>
              </widget>
             </item>
             <item row="2" column="0">
              <widget class="QCheckBox" name="compilationStats_checkBox">
               <property name="toolTip">
                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Output compilation statistics with &lt;span style=&quot; font-family: monospace&quot;&gt;--compiler-statistics&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
               </property>
               <property name="text">
                <string>Output compilation statistics</string>
               </property>
              </widget>
             </item>
             <item row="3" column="0">
              <widget class="QCheckBox" name="timingInfo_checkBox">
               <property name="toolTip">
                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Output timing information with &lt;span style=&quot; font-family:'monospace';&quot;&gt;--output-time&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
               </property>
               <property name="text">
                <string>Output timing information</string>
               </property>
              </widget>
             </item>
             <item row="1" column="0" colspan="2">
              <widget class="Line" name="line_2">
               <property name="orientation">
                <enum>Qt::Horizontal</enum>
               </property>
              </widget>
             </item>
             <item row="3" column="1">
              <widget class="QCheckBox" name="outputObjective_checkBox">
               <property name="text">
                <string>Output objective value</string>
               </property>
              </widget>
             </item>
            </layout>
           </item>
          </layout>
         </widget>
        </item>
       </layout>
      </widget>
     </item>
     <item>
      <widget class="QGroupBox" name="advanced_groupBox">
       <property name="title">
        <string>Advanced options</string>
       </property>
       <layout class="QVBoxLayout" name="verticalLayout_14">
        <item>
         <widget class="QGroupBox" name="compiling_groupBox">
          <property name="title">
           <string>Compiling</string>
          </property>
          <layout class="QHBoxLayout" name="horizontalLayout_5">
           <item>
            <layout class="QGridLayout" name="gridLayout_3">
             <item row="0" column="0">
              <widget class="QLabel" name="label_21">
               <property name="toolTip">
                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Compiler optimization level&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
               </property>
               <property name="text">
                <string>Optimization level:</string>
               </property>
              </widget>
             </item>
             <item row="0" column="1">
              <widget class="QComboBox" name="optimizationLevel_comboBox">
               <property name="currentIndex">
                <number>1</number>
               </property>
               <item>
                <property name="text">
                 <string>-O0 (no optimization)</string>
                </property>
               </item>
               <item>
                <property name="text">
                 <string>-O1 (default)</string>
                </property>
               </item>
               <item>
                <property name="text">
                 <string>-O2 (two pass compilation)</string>
                </property>
               </item>
               <item>
                <property name="text">
                 <string>-O3 (two pass compilation with Gecode)</string>
                </property>
               </item>
               <item>
                <property name="text">
                 <string>-O4 (as -O3 with shaving)</string>
                </property>
               </item>
               <item>
                <property name="text">
                 <string>-O5 (as -O3 with singleton arc consistency)</string>
                </property>
               </item>
              </widget>
             </item>
             <item row="1" column="0">
              <widget class="QLabel" name="label_22">
               <property name="toolTip">
                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Additional string data input with &lt;span style=&quot; font-family:monospace;&quot;&gt;-D&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
               </property>
               <property name="text">
                <string>Additional data:</string>
               </property>
              </widget>
             </item>
             <item row="1" column="1">
              <widget class="QPlainTextEdit" name="additionalData_plainTextEdit">
               <property name="maximumSize">
                <size>
                 <width>16777215</width>
                 <height>40</height>
                </size>
               </property>
              </widget>
             </item>
            </layout>
           </item>
          </layout>
         </widget>
        </item>
        <item>
         <widget class="QGroupBox" name="solving_groupBox_2">
          <property name="title">
           <string>Solving</string>
          </property>
          <layout class="QHBoxLayout" name="horizontalLayout_6">
           <item>
            <layout class="QGridLayout" name="gridLayout_5">
             <item row="0" column="0">
              <widget class="QLabel" name="label_23">
               <property name="toolTip">
                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sets the number of solver threads with &lt;span style=&quot; font-family:monospace;&quot;&gt;-p&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
               </property>
               <property name="text">
                <string>Number of threads:</string>
               </property>
              </widget>
             </item>
             <item row="0" column="1">
              <widget class="QSpinBox" name="numThreads_spinBox">
               <property name="alignment">
                <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
               </property>
               <property name="minimum">
                <number>1</number>
               </property>
               <property name="maximum">
                <number>9999</number>
               </property>
               <property name="value">
                <number>1</number>
               </property>
              </widget>
             </item>
             <item row="1" column="0">
              <widget class="QCheckBox" name="randomSeed_checkBox">
               <property name="toolTip">
                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sets the random seed for the solver with &lt;span style=&quot; font-family:monospace;&quot;&gt;-r&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
               </property>
               <property name="text">
                <string>Random seed:</string>
               </property>
              </widget>
             </item>
             <item row="1" column="1">
              <widget class="QLineEdit" name="randomSeed_lineEdit">
               <property name="enabled">
                <bool>false</bool>
               </property>
              </widget>
             </item>
             <item row="2" column="0">
              <widget class="QCheckBox" name="freeSearch_checkBox">
               <property name="toolTip">
                <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable free search with &lt;span style=&quot; font-family:'monospace';&quot;&gt;-f&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
               </property>
               <property name="text">
                <string>Free search</string>
               </property>
              </widget>
             </item>
            </layout>
           </item>
          </layout>
         </widget>
        </item>
        <item>
         <widget class="QGroupBox" name="unknownOptions_groupBox">
          <property name="toolTip">
           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Extra parameters passed to MiniZinc&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
          </property>
          <property name="title">
           <string>Extra configuration parameters</string>
          </property>
          <layout class="QVBoxLayout" name="verticalLayout_3">
           <item>
            <widget class="QTableWidget" name="extraParams_tableWidget">
             <property name="verticalScrollBarPolicy">
              <enum>Qt::ScrollBarAsNeeded</enum>
             </property>
             <property name="sizeAdjustPolicy">
              <enum>QAbstractScrollArea::AdjustToContents</enum>
             </property>
             <property name="editTriggers">
              <set>QAbstractItemView::AllEditTriggers</set>
             </property>
             <property name="selectionBehavior">
              <enum>QAbstractItemView::SelectRows</enum>
             </property>
             <attribute name="horizontalHeaderStretchLastSection">
              <bool>true</bool>
             </attribute>
             <attribute name="verticalHeaderVisible">
              <bool>false</bool>
             </attribute>
             <column>
              <property name="text">
               <string>Parameter</string>
              </property>
             </column>
             <column>
              <property name="text">
               <string>Flag Type</string>
              </property>
             </column>
             <column>
              <property name="text">
               <string>Data Type</string>
              </property>
             </column>
             <column>
              <property name="text">
               <string>Value</string>
              </property>
             </column>
            </widget>
           </item>
           <item>
            <layout class="QHBoxLayout" name="horizontalLayout_2">
             <item>
              <spacer name="horizontalSpacer_2">
               <property name="orientation">
                <enum>Qt::Horizontal</enum>
               </property>
               <property name="sizeHint" stdset="0">
                <size>
                 <width>40</width>
                 <height>20</height>
                </size>
               </property>
              </spacer>
             </item>
             <item>
              <widget class="QToolButton" name="addExtraParam_toolButton">
               <property name="text">
                <string>Add parameter</string>
               </property>
               <property name="popupMode">
                <enum>QToolButton::InstantPopup</enum>
               </property>
               <property name="toolButtonStyle">
                <enum>Qt::ToolButtonTextOnly</enum>
               </property>
               <property name="arrowType">
                <enum>Qt::DownArrow</enum>
               </property>
              </widget>
             </item>
             <item>
              <widget class="QToolButton" name="removeExtraParam_toolButton">
               <property name="enabled">
                <bool>false</bool>
               </property>
               <property name="text">
                <string>Remove parameter</string>
               </property>
               <property name="toolButtonStyle">
                <enum>Qt::ToolButtonTextOnly</enum>
               </property>
              </widget>
             </item>
            </layout>
           </item>
          </layout>
         </widget>
        </item>
       </layout>
      </widget>
     </item>
    </layout>
   </item>
   <item>
    <spacer name="verticalSpacer">
     <property name="orientation">
      <enum>Qt::Vertical</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>20</width>
       <height>40</height>
      </size>
     </property>
    </spacer>
   </item>
  </layout>
  <action name="actionCustom_Parameter">
   <property name="text">
    <string>Custom parameter</string>
   </property>
   <property name="toolTip">
    <string>Add custom parameter to configuration</string>
   </property>
  </action>
  <action name="actionAdd_all_known_parameters">
   <property name="text">
    <string>Add all known parameters</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections/>
</ui>


================================================
FILE: MiniZincIDE/dark_mode.css
================================================
*,
QTableView::item {
    border-color: #444444;
    color: #FFFFFF;
}

QMainWindow, QDialog, QToolBar, QAbstractScrollArea, QAction, QDockWidget {
    background-color: #333333;
    alternate-background-color: #444444;
}

*:disabled {
    background-color: #333333;
    color: #666666;
    border-color: #666666;
}

QMenuBar, QPushButton, QToolButton,
QTabWidget::pane QMenuBar, QTabWidget::pane QPushButton, QTabWidget::pane QToolButton {
    background-color: #444444;
}

QToolBar::separator {
    background-color: #444444;
    width: 1px;
    margin: 6px;
}

QMenuBar::item:selected, QMenu::item:selected {
    background-color: #555555;
}

QMenuBar::item:pressed {
    background-color: #666666;
}

QMenu {
    background-color: #3D3D3D;
}

QTabWidget::tab-bar, QTabWidget::pane, QTabBar {
    border: 0;
}


QTabWidget::tab-bar, QTabBar {
    background-color: #444444;
}

QTabBar::tab {
    background-color: #3A3A3A;
}

QTabBar::tab:selected {
    background-color: #262626;
}

QTabBar::tab:hover {
    background-color: #2D2D2D;
}

QTabWidget::pane, QTabWidget::pane * {
    background-color: #262626;
}

QPlainTextEdit,
QTextEdit,
QLineEdit,
QComboBox,
QAbstractSlider,
QAbstractSpinBox,
QListView,
QTreeView,
QTableView,
QTableView::item
{
    background-color: #222222;
    padding: 3px;
    border: 1px solid #666666;
}


QTabWidget::pane QPlainTextEdit,
QTabWidget::pane QTextEdit,
QTabWidget::pane QLineEdit,
QTabWidget::pane QComboBox,
QTabWidget::pane QAbstractSlider,
QTabWidget::pane QAbstractSpinBox,
QTabWidget::pane QListView,
QTabWidget::pane QTreeView,
QTabWidget::pane QTableView,
QTabWidget::pane QTableView::item
{
    background-color: #1D1D1D;
    padding: 3px;
    border: 1px solid #666666;
}

QGroupBox {
    border: 1px solid #666666;
    margin-top: 1.5ex;
    margin-bottom: 1.5ex;
    padding: 1ex;
    padding-top: 2ex;
}

QGroupBox::title {
    subcontrol-origin: margin;
    subcontrol-position: top left;
    left: 5px;
    padding: 0 1ex;
}

QToolTip {
    color: #000000;
}

QDockWidget::title {
    background-color: #222222;
    text-align: left center;
}

QDockWidget::close-button, QDockWidget::float-button {
    background-color: #000000;
}

QStatusBar QLabel {
    padding-left: 1ex;
    padding-right: 1ex;
}

QStatusBar::item {
    border: 0;
}

QScrollBar {
    color: #555555;
}

QScrollBar:vertical {
    margin-top: 16px;
    margin-bottom: 16px;
}

QScrollBar:horizontal {
    margin-left: 16px;
    margin-right: 16px;
}

QScrollBar::handle {
    border: 0;
    background: #444444;
}

QScrollBar::handle:vertical {
    min-height: 20px;
}

QScrollBar::handle:horizontal {
    min-width: 20px;
}

QScrollBar::add-page, QScrollBar::sub-page {
    background: none;
}

QScrollBar::add-line:vertical {
    height: 16px;
    subcontrol-position: bottom;
    subcontrol-origin: margin;
}

QScrollBar::sub-line:vertical {
    height: 16px;
    subcontrol-position: top;
    subcontrol-origin: margin;
}

QScrollBar::add-line:horizontal {
    width: 16px;
    subcontrol-position: right;
    subcontrol-origin: margin;
    border: 0;
}

QScrollBar::sub-line:horizontal {
    width: 16px;
    subcontrol-position: left;
    subcontrol-origin: margin;
    border: 0;
}

QHeaderView::section {
    background-color: #333333;
}


================================================
FILE: MiniZincIDE/darkmodenotifier.cpp
================================================
#include "darkmodenotifier.h"

#include <QApplication>
#include <QSettings>

DarkModeNotifier::DarkModeNotifier(QObject *parent) : QObject(parent)
{
    init();

    if (!hasSystemSetting()) {
        QSettings settings;
        settings.beginGroup("MainWindow");
        _darkMode = settings.value("darkMode", false).value<bool>();
    }
}

void DarkModeNotifier::requestChangeDarkMode(bool enable)
{
    if (hasSystemSetting()) {
        // Can't change dark mode since we're using system setting
        return;
    }
    if (enable != _darkMode) {
        _darkMode = enable;
        emit darkModeChanged(_darkMode);
    }
}

#ifdef Q_OS_WIN

#include <QWinEventNotifier>

#define NOMINMAX
#include <Windows.h>

class DarkModeNotifier::Internal
{
public:
    QWinEventNotifier* notifier = nullptr;

    HKEY hKey = nullptr;
    HANDLE hEvent = nullptr;

    bool ok = true;
};

void DarkModeNotifier::init()
{
    auto getDarkMode = [=] () {
        if (!_internal->ok) { return false; }
        DWORD value = 1;
        DWORD size = sizeof(DWORD);
        auto result = RegGetValue(_internal->hKey, nullptr, L"AppsUseLightTheme", RRF_RT_REG_DWORD, nullptr, &value, &size);
        if (result != ERROR_SUCCESS) {
            _internal->ok = false;
            return false;
        }
        return value == 0;
    };

    _internal = new Internal;

    // Get dark mode registry key
    auto result = RegOpenKey(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", &_internal->hKey);
    _internal->ok = result == ERROR_SUCCESS;
    if (!_internal->ok) { return; }

    // Get initial dark mode
    _darkMode = getDarkMode();
    if (!_internal->ok) { return; }

    // Setup event to be triggered on registry change
    _internal->hEvent = CreateEvent(nullptr, true, false, nullptr);
    _internal->ok = _internal->hEvent != nullptr;
    if (!_internal->ok) { return; }

    // Listen for event
    _internal->notifier = new QWinEventNotifier(_internal->hEvent);
    connect(_internal->notifier, &QWinEventNotifier::activated, this, [=] () {
        bool newDarkMode = getDarkMode();
        if (!_internal->ok) { return; }
        if (newDarkMode != _darkMode) {
            _darkMode = newDarkMode;
            emit darkModeChanged(newDarkMode);
        }
        _internal->ok = ResetEvent(_internal->hEvent) != 0;
        if (!_internal->ok) { return; }
        auto result = RegNotifyChangeKeyValue(_internal->hKey,
                                              true,
                                              REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET,
                                              _internal->hEvent,
                                              true);
        _internal->ok = result == ERROR_SUCCESS;
    });

    // Start notifier
    result = RegNotifyChangeKeyValue(_internal->hKey,
                                     true,
                                     REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET,
                                     _internal->hEvent,
                                     true);
    _internal->ok = result == ERROR_SUCCESS;
}

DarkModeNotifier::~DarkModeNotifier()
{
    delete _internal->notifier;
    CloseHandle(_internal->hEvent);
    RegCloseKey(_internal->hKey);
    delete _internal;
}

bool DarkModeNotifier::hasSystemSetting() const
{
    return _internal->ok;
}

bool DarkModeNotifier::hasNativeDarkMode() const
{
#if QT_VERSION < 0x060500
    // Have to style using CSS, no native dark widgets
    return false;
#else
    if (hasSystemSetting()) {
        QApplication::setStyle("Fusion");
        return true;
    }
    return false;
#endif
}

#elif !defined(Q_OS_MAC)

// No support for system dark mode

void DarkModeNotifier::init() {}

DarkModeNotifier::~DarkModeNotifier() {}

bool DarkModeNotifier::hasSystemSetting() const
{
    return false;
}

bool DarkModeNotifier::hasNativeDarkMode() const
{
    // Have to style using CSS, no native dark widgets
    return false;
}

#endif


================================================
FILE: MiniZincIDE/darkmodenotifier.h
================================================
#ifndef DARKMODENOTIFIER_H
#define DARKMODENOTIFI
Download .txt
gitextract_jgwfs6f5/

├── .envrc
├── .gitignore
├── .gitlab-ci.yml
├── LICENSE.txt
├── MiniZincIDE/
│   ├── CHANGES
│   ├── MiniZincIDE.pri
│   ├── MiniZincIDE.pro
│   ├── README.txt
│   ├── cheat_sheet.mzn
│   ├── checkupdatedialog.cpp
│   ├── checkupdatedialog.h
│   ├── checkupdatedialog.ui
│   ├── codechecker.cpp
│   ├── codechecker.h
│   ├── codeeditor.cpp
│   ├── codeeditor.h
│   ├── configwindow.cpp
│   ├── configwindow.h
│   ├── configwindow.ui
│   ├── dark_mode.css
│   ├── darkmodenotifier.cpp
│   ├── darkmodenotifier.h
│   ├── darkmodenotifier_macos.mm
│   ├── elapsedtimer.cpp
│   ├── elapsedtimer.h
│   ├── esclineedit.cpp
│   ├── esclineedit.h
│   ├── exception.h
│   ├── extraparamdialog.cpp
│   ├── extraparamdialog.h
│   ├── extraparamdialog.ui
│   ├── fzndoc.cpp
│   ├── fzndoc.h
│   ├── gotolinedialog.cpp
│   ├── gotolinedialog.h
│   ├── gotolinedialog.ui
│   ├── highlighter.cpp
│   ├── highlighter.h
│   ├── history.cpp
│   ├── history.h
│   ├── ide.cpp
│   ├── ide.h
│   ├── ideutils.cpp
│   ├── ideutils.h
│   ├── images/
│   │   └── about.html
│   ├── main.cpp
│   ├── mainwindow.cpp
│   ├── mainwindow.h
│   ├── mainwindow.ui
│   ├── minizincide.qrc
│   ├── moocsubmission.cpp
│   ├── moocsubmission.h
│   ├── moocsubmission.ui
│   ├── mznide-makefile.plist
│   ├── mznide-xcode.plist
│   ├── mznide.icns
│   ├── outputdockwidget.cpp
│   ├── outputdockwidget.h
│   ├── outputwidget.cpp
│   ├── outputwidget.h
│   ├── outputwidget.ui
│   ├── paramdialog.cpp
│   ├── paramdialog.h
│   ├── paramdialog.ui
│   ├── preferencesdialog.cpp
│   ├── preferencesdialog.h
│   ├── preferencesdialog.ui
│   ├── process.cpp
│   ├── process.h
│   ├── profilecompilation.cpp
│   ├── profilecompilation.h
│   ├── project.cpp
│   ├── project.h
│   ├── projectbrowser.cpp
│   ├── projectbrowser.h
│   ├── projectbrowser.ui
│   ├── server/
│   │   ├── connector.js
│   │   └── index.html
│   ├── server.cpp
│   ├── server.h
│   ├── solver.cpp
│   ├── solver.h
│   ├── theme.cpp
│   └── theme.h
├── MiniZincIDE.pro
├── README.md
├── TODO.txt
├── cp-profiler/
│   ├── README.md
│   ├── cp-profiler.pri
│   ├── cp-profiler.pro
│   └── src/
│       ├── cpp-integration/
│       │   ├── README.md
│       │   ├── connector.hpp
│       │   └── message.hpp
│       ├── cpprofiler/
│       │   ├── analysis/
│       │   │   ├── histogram_scene.cpp
│       │   │   ├── histogram_scene.hh
│       │   │   ├── merge_window.cpp
│       │   │   ├── merge_window.hh
│       │   │   ├── merging/
│       │   │   │   ├── merge_result.hh
│       │   │   │   ├── pentagon_list_widget.hh
│       │   │   │   ├── pentagon_rect.cpp
│       │   │   │   └── pentagon_rect.hh
│       │   │   ├── nogood_analysis_dialog.hh
│       │   │   ├── path_comp.cpp
│       │   │   ├── path_comp.hh
│       │   │   ├── pattern_rect.cpp
│       │   │   ├── pattern_rect.hh
│       │   │   ├── pentagon_counter.hpp
│       │   │   ├── similar_subtree_analysis.cpp
│       │   │   ├── similar_subtree_analysis.hh
│       │   │   ├── similar_subtree_window.cpp
│       │   │   ├── similar_subtree_window.hh
│       │   │   ├── subtree_pattern.hh
│       │   │   ├── tree_merger.cpp
│       │   │   └── tree_merger.hh
│       │   ├── command_line_parser.cpp
│       │   ├── command_line_parser.hh
│       │   ├── conductor.cpp
│       │   ├── conductor.hh
│       │   ├── config.hh
│       │   ├── core.cpp
│       │   ├── core.hh
│       │   ├── db_handler.cpp
│       │   ├── db_handler.hh
│       │   ├── execution.cpp
│       │   ├── execution.hh
│       │   ├── execution_list.cpp
│       │   ├── execution_list.hh
│       │   ├── execution_window.cpp
│       │   ├── execution_window.hh
│       │   ├── message_wrapper.hh
│       │   ├── name_map.cpp
│       │   ├── name_map.hh
│       │   ├── nogood_dialog.cpp
│       │   ├── nogood_dialog.hh
│       │   ├── options.hh
│       │   ├── pixel_views/
│       │   │   ├── icicle_canvas.cpp
│       │   │   ├── icicle_canvas.hh
│       │   │   ├── pixel_image.cpp
│       │   │   ├── pixel_image.hh
│       │   │   ├── pixel_item.hh
│       │   │   ├── pixel_widget.cpp
│       │   │   ├── pixel_widget.hh
│       │   │   ├── pt_canvas.cpp
│       │   │   └── pt_canvas.hh
│       │   ├── receiver_thread.cpp
│       │   ├── receiver_thread.hh
│       │   ├── receiver_worker.cpp
│       │   ├── receiver_worker.hh
│       │   ├── settings.hh
│       │   ├── solver_data.cpp
│       │   ├── solver_data.hh
│       │   ├── solver_id.hh
│       │   ├── stats_bar.hpp
│       │   ├── tcp_server.cpp
│       │   ├── tcp_server.hh
│       │   ├── tests/
│       │   │   ├── execution_test.cpp
│       │   │   ├── execution_test.hh
│       │   │   ├── tree_test.cpp
│       │   │   └── tree_test.hh
│       │   ├── tree/
│       │   │   ├── cursors/
│       │   │   │   ├── drawing_cursor.cpp
│       │   │   │   ├── drawing_cursor.hh
│       │   │   │   ├── hide_failed_cursor.cpp
│       │   │   │   ├── hide_failed_cursor.hh
│       │   │   │   ├── hide_not_highlighted_cursor.cpp
│       │   │   │   ├── hide_not_highlighted_cursor.hh
│       │   │   │   ├── layout_cursor.cpp
│       │   │   │   ├── layout_cursor.hh
│       │   │   │   ├── node_cursor.cpp
│       │   │   │   ├── node_cursor.hh
│       │   │   │   ├── nodevisitor.hh
│       │   │   │   └── nodevisitor.hpp
│       │   │   ├── layout.cpp
│       │   │   ├── layout.hh
│       │   │   ├── layout_computer.cpp
│       │   │   ├── layout_computer.hh
│       │   │   ├── node.cpp
│       │   │   ├── node.hh
│       │   │   ├── node_drawing.cpp
│       │   │   ├── node_drawing.hh
│       │   │   ├── node_id.cpp
│       │   │   ├── node_id.hh
│       │   │   ├── node_info.cpp
│       │   │   ├── node_info.hh
│       │   │   ├── node_stats.hh
│       │   │   ├── node_tree.cpp
│       │   │   ├── node_tree.hh
│       │   │   ├── node_widget.hh
│       │   │   ├── shape.cpp
│       │   │   ├── shape.hh
│       │   │   ├── structure.cpp
│       │   │   ├── structure.hh
│       │   │   ├── subtree_view.hh
│       │   │   ├── traditional_view.cpp
│       │   │   ├── traditional_view.hh
│       │   │   ├── tree_scroll_area.cpp
│       │   │   ├── tree_scroll_area.hh
│       │   │   ├── visual_flags.cpp
│       │   │   └── visual_flags.hh
│       │   ├── tree_builder.cpp
│       │   ├── tree_builder.hh
│       │   ├── user_data.cpp
│       │   ├── user_data.hh
│       │   └── utils/
│       │       ├── array.cpp
│       │       ├── array.hh
│       │       ├── debug.hh
│       │       ├── debug_mutex.hh
│       │       ├── maybe_caller.cpp
│       │       ├── maybe_caller.hh
│       │       ├── path_utils.cpp
│       │       ├── path_utils.hh
│       │       ├── perf_helper.cpp
│       │       ├── perf_helper.hh
│       │       ├── std_ext.cpp
│       │       ├── std_ext.hh
│       │       ├── string_utils.cpp
│       │       ├── string_utils.hh
│       │       ├── tree_utils.cpp
│       │       ├── tree_utils.hh
│       │       ├── utils.cpp
│       │       └── utils.hh
│       └── main_cpprofiler.cpp
├── default.nix
├── flake.nix
├── resources/
│   ├── README.md
│   ├── misc/
│   │   ├── COMBINED_LICENSE.txt
│   │   ├── MiniZincIDE.desktop
│   │   ├── README
│   │   ├── entitlements.xml
│   │   ├── minizinc.desktop
│   │   ├── osx-gecode-qt.conf
│   │   └── win-gecode-qt.conf
│   ├── pkg_config/
│   │   ├── Dockerfile
│   │   ├── minizinc-bundle.iss
│   │   └── snapcraft.yaml
│   └── scripts/
│       ├── AppRun
│       └── MiniZincIDE.sh
└── tests/
    ├── data/
    │   ├── mooc/
    │   │   ├── TestProject/
    │   │   │   ├── TestProject.mzp
    │   │   │   ├── _mooc
    │   │   │   ├── data/
    │   │   │   │   ├── n1.dzn
    │   │   │   │   └── n2.dzn
    │   │   │   └── models/
    │   │   │       ├── submission.mzc
    │   │   │       └── submission.mzn
    │   │   └── TestTerms/
    │   │       ├── TestTerms.mzp
    │   │       ├── _mooc
    │   │       ├── data/
    │   │       │   ├── n1.dzn
    │   │       │   └── n2.dzn
    │   │       └── models/
    │   │           ├── submission.mzc
    │   │           └── submission.mzn
    │   └── project/
    │       ├── configs/
    │       │   ├── solver1.mpc
    │       │   ├── solver2.mpc
    │       │   └── solver3.mpc
    │       ├── data/
    │       │   ├── data1.dzn
    │       │   └── data2.dzn
    │       ├── models/
    │       │   ├── model1.mzn
    │       │   └── model2.mzn
    │       ├── project-105-bad.mzp
    │       ├── project-105-good.mzp
    │       ├── project-106-bad.mzp
    │       └── project-106-good.mzp
    ├── testcpprofier.cpp
    ├── testdiff.cpp
    ├── testeditor.cpp
    ├── testide.cpp
    ├── testide.h
    ├── testmooc.cpp
    ├── testproject.cpp
    └── tests.pro
Download .txt
SYMBOL INDEX (1067 symbols across 176 files)

FILE: MiniZincIDE/checkupdatedialog.h
  function namespace (line 6) | namespace Ui {
  function class (line 10) | class CheckUpdateDialog : public QDialog

FILE: MiniZincIDE/codechecker.h
  function class (line 9) | class CodeChecker : public QObject

FILE: MiniZincIDE/codeeditor.cpp
  function Highlighter (line 174) | Highlighter& CodeEditor::getHighlighter() {
  function foreach (line 415) | foreach (QTextEdit::ExtraSelection sel, allExtraSels) {
  function QColor (line 587) | QColor CodeEditor::interpolate(QColor start,QColor end,double ratio)
  function QColor (line 599) | QColor CodeEditor::heatColor(double ratio)
  function foreach (line 713) | foreach (CodeEditorError cee, errors) {
  function foreach (line 761) | foreach (QTextEdit::ExtraSelection sel, allExtraSels) {

FILE: MiniZincIDE/codeeditor.h
  type MiniZincError (line 34) | struct MiniZincError {
  function class (line 46) | class CodeEditor : public QPlainTextEdit
  function class (line 124) | class LineNumbers: public QWidget
  function class (line 142) | class DebugInfo: public QWidget
  function class (line 160) | class EditorHeader: public QWidget

FILE: MiniZincIDE/configwindow.cpp
  function QString (line 267) | QString ConfigWindow::saveConfig(int index)
  function QString (line 305) | QString ConfigWindow::saveConfig()
  function SolverConfiguration (line 310) | SolverConfiguration* ConfigWindow::currentSolverConfig(void)
  function QWidget (line 777) | QWidget* ExtraOptionDelegate::createEditor(QWidget* parent, const QStyle...
  function SolverConfiguration (line 962) | SolverConfiguration* ConfigWindow::StashItem::consume() {

FILE: MiniZincIDE/configwindow.h
  function namespace (line 25) | namespace Ui {
  function class (line 29) | class ConfigWindow : public QWidget
  function class (line 180) | class ExtraOptionDelegate : public QStyledItemDelegate {
  function class (line 190) | class LongLongValidator : public QValidator {

FILE: MiniZincIDE/darkmodenotifier.cpp
  class DarkModeNotifier::Internal (line 36) | class DarkModeNotifier::Internal

FILE: MiniZincIDE/darkmodenotifier.h
  function class (line 6) | class DarkModeNotifier : public QObject

FILE: MiniZincIDE/elapsedtimer.cpp
  function qint64 (line 9) | qint64 ElapsedTimer::elapsed()

FILE: MiniZincIDE/elapsedtimer.h
  function class (line 9) | class ElapsedTimer: public QObject

FILE: MiniZincIDE/esclineedit.h
  function class (line 6) | class EscLineEdit : public QLineEdit

FILE: MiniZincIDE/exception.h
  function class (line 6) | class Exception : public QException
  function class (line 20) | class InternalError : public Exception
  function class (line 29) | class ProcessError : public Exception
  function class (line 38) | class ProjectError : public Exception
  function class (line 47) | class MoocError : public Exception
  function class (line 56) | class ConfigError : public Exception
  function class (line 65) | class DriverError : public Exception
  function class (line 74) | class FileError : public Exception
  function class (line 83) | class ServerError : public Exception

FILE: MiniZincIDE/extraparamdialog.h
  function namespace (line 10) | namespace Ui {
  function class (line 14) | class ExtraParamDialog : public QWidget

FILE: MiniZincIDE/fzndoc.h
  function class (line 18) | class FznDoc : public QObject

FILE: MiniZincIDE/gotolinedialog.h
  function namespace (line 18) | namespace Ui {
  function class (line 22) | class GoToLineDialog : public QDialog

FILE: MiniZincIDE/highlighter.cpp
  function uint (line 77) | uint qHash(const FixedBg& key) {
  function fg_contains (line 81) | bool fg_contains(const FixedBg& a, const FixedBg& b) {
  function foreach (line 292) | foreach(const QTextLayout::FormatRange& fr, block.textFormats()) {
  function foreach (line 336) | foreach(const QTextLayout::FormatRange &range, layout->formats()) {

FILE: MiniZincIDE/highlighter.h
  type Bracket (line 22) | struct Bracket {
  function class (line 27) | class DebugInfoData {
  function reset (line 37) | void reset(void) { con=0; var=0; ms=0; totalCon=0; totalVar=0; totalMs=1; }
  function QString (line 38) | QString toString(void) {
  type HighlightingState (line 43) | enum HighlightingState { HS_NONE=-1, HS_STRING, HS_INTERPOLATE, HS_COMME...
  function class (line 45) | class BracketData : public QTextBlockUserData
  type FixedBg (line 53) | struct FixedBg {
  type QHash (line 59) | typedef QHash<FixedBg, QPair<QColor, QString> > BgMap;
  function class (line 66) | class Highlighter : public QSyntaxHighlighter

FILE: MiniZincIDE/history.cpp
  function QString (line 82) | QString FileDiff::apply(const QString& source, const QVector<FileDiff::E...
  function QJsonObject (line 149) | QJsonObject History::toJSON() const

FILE: MiniZincIDE/history.h
  type class (line 15) | enum class
  type Entry (line 20) | struct Entry {
  type Change (line 88) | struct Change {
  type FileHistory (line 93) | struct FileHistory {

FILE: MiniZincIDE/ide.cpp
  function QVariantMap (line 37) | QVariantMap IDEStatistics::toVariantMap(void) {
  function QByteArray (line 46) | QByteArray IDEStatistics::toJson(void) {
  type IDE::Doc (line 57) | struct IDE::Doc {
    method Doc (line 61) | Doc() {
  function foreach (line 254) | foreach (QObject* mo, lst) {
  function QString (line 435) | QString IDE::getLastPath(void) {
  function QTextDocument (line 509) | QTextDocument* IDE::addDocument(const QString& path, QTextDocument *doc,...
  function QString (line 671) | QString IDE::appDir(void) const {
  function IDE (line 679) | IDE* IDE::instance(void) {

FILE: MiniZincIDE/ide.h
  function class (line 31) | class IDEStatistics {
  function class (line 44) | class IDE : public QApplication {

FILE: MiniZincIDE/ideutils.cpp
  type IDEUtils (line 15) | namespace IDEUtils {
    function QString (line 17) | QString formatTime(qint64 time) {
    function isChildPath (line 41) | bool isChildPath(const QString& parent, const QString& child)
    function watchChildChanges (line 47) | void watchChildChanges(QWidget* target, QObject* receiver, std::functi...
    function QFont (line 79) | QFont fontFromString(const QString& s)

FILE: MiniZincIDE/ideutils.h
  function namespace (line 10) | namespace IDEUtils {
  function class (line 20) | class MimeDataExporter : public QTextEdit {

FILE: MiniZincIDE/main.cpp
  function main (line 16) | int main(int argc, char *argv[])

FILE: MiniZincIDE/mainwindow.cpp
  function QString (line 452) | QString MainWindow::getLastPath(void)
  function QString (line 908) | QString MainWindow::currentModelFile()
  function QString (line 1000) | QString MainWindow::setElapsedTime(qint64 elapsed_t)
  function QString (line 1394) | QString MainWindow::currentSolverConfigName(void) {
  function getBlocksFromPath (line 1823) | QVector<QStringList> getBlocksFromPath(QString& path) {
  function SolverConfiguration (line 2694) | SolverConfiguration* MainWindow::getCurrentSolverConfig()
  function Solver (line 2699) | const Solver* MainWindow::getCurrentSolver()
  function QStringList (line 2737) | QStringList MainWindow::getOpenFiles()
  function QString (line 3050) | QString MainWindow::locationToLink(const QString& file, int firstLine, i...

FILE: MiniZincIDE/mainwindow.h
  function namespace (line 48) | namespace Ui {
  function class (line 57) | class MainWindow : public QMainWindow

FILE: MiniZincIDE/moocsubmission.h
  function namespace (line 14) | namespace Ui {
  function class (line 32) | class MOOCAssignment {
  function class (line 57) | class MOOCSubmission : public QDialog

FILE: MiniZincIDE/outputdockwidget.h
  function class (line 6) | class OutputDockWidget : public QDockWidget

FILE: MiniZincIDE/outputwidget.cpp
  function QString (line 103) | QString OutputWidget::lastTraceLoc(const QString &newTraceLoc)
  function QTextCursor (line 779) | QTextCursor OutputWidget::fragmentCursor(int position)
  function QSizeF (line 936) | QSizeF OutputWidgetArrow::intrinsicSize(QTextDocument* doc, int posInDoc...
  function QTextCursor (line 1029) | QTextCursor OutputWidget::nextInsertAt() const

FILE: MiniZincIDE/outputwidget.h
  function namespace (line 12) | namespace Ui {
  type TextObject (line 25) | enum TextObject {
  type Property (line 29) | enum Property {
  function isSectionVisible (line 36) | bool isSectionVisible(const QString& section) { return _sections.value(s...
  function isMessageTypeVisible (line 37) | bool isMessageTypeVisible(const QString& messageType) { return _messageT...
  function solutionLimit (line 48) | int solutionLimit() { return _solutionLimit; }
  function setSolutionLimit (line 75) | void setSolutionLimit(int solutionLimit) { _solutionLimit = solutionLimi...
  function toggleSectionVisibility (line 79) | void toggleSectionVisibility(const QString& section) { setSectionVisibil...
  function toggleMessageTypeVisibility (line 83) | void toggleMessageTypeVisibility(const QString& messageType) { setMessag...

FILE: MiniZincIDE/paramdialog.h
  function namespace (line 21) | namespace Ui {
  function class (line 25) | class ParamDialog : public QDialog

FILE: MiniZincIDE/preferencesdialog.cpp
  function QByteArray (line 182) | QByteArray PreferencesDialog::allowFileRestore(const QString& path)
  function clearRequiredFlagsLayout (line 509) | void clearRequiredFlagsLayout(QGridLayout* l) {

FILE: MiniZincIDE/preferencesdialog.h
  function namespace (line 9) | namespace Ui {
  function class (line 13) | class PreferencesDialog : public QDialog

FILE: MiniZincIDE/process.cpp
  function Solver (line 226) | Solver* MznDriver::defaultSolver(void)
  function qint64 (line 455) | qint64 MznProcess::elapsedTime()
  function QString (line 470) | QString MznProcess::command() const

FILE: MiniZincIDE/process.h
  function class (line 23) | class Process : public QProcess {
  function isValid (line 69) | bool isValid(void) const
  function QStringList (line 81) | const QStringList& minizincExecutable(void) const
  function QString (line 89) | const QString& mznDistribPath(void) const
  function QString (line 97) | const QString& minizincVersionString(void) const
  function QString (line 105) | const QString& userSolverConfigDir(void) const
  function QString (line 113) | const QString& userConfigFile(void) const
  function QString (line 121) | const QString& mznStdlibDir(void) const
  function QVersionNumber (line 150) | const QVersionNumber& version(void)
  function clear (line 167) | void clear()

FILE: MiniZincIDE/profilecompilation.h
  function class (line 11) | class Path
  function class (line 33) | class PathEntry
  function class (line 50) | class TimingEntry

FILE: MiniZincIDE/project.cpp
  function QStringList (line 74) | QStringList Project::loadProject(const QString& file, ConfigWindow* conf...
  function QStringList (line 398) | QStringList Project::files(void) const {
  function QStringList (line 402) | QStringList Project::modelFiles(void) const {
  function QStringList (line 406) | QStringList Project::solverConfigurationFiles(void) const {
  function QStringList (line 410) | QStringList Project::dataFiles(void) const {
  function QDir (line 448) | QDir Project::rootDir()
  function QString (line 464) | QString Project::getFileName(const QModelIndex& index)
  function QStringList (line 469) | QStringList Project::getFileNames(const QModelIndexList& indices)
  function QStringList (line 478) | QStringList Project::getFiles(NodeType type) const
  function QString (line 490) | QString Project::relativeToProject(const QString& fileName)

FILE: MiniZincIDE/project.h
  function class (line 25) | class Project : public QObject {

FILE: MiniZincIDE/projectbrowser.h
  function namespace (line 13) | namespace Ui {
  function class (line 17) | class ProjectBrowser : public QWidget

FILE: MiniZincIDE/server.cpp
  function VisConnector (line 230) | VisConnector* Server::addConnector(const QString& label, const QStringLi...

FILE: MiniZincIDE/server.h
  function class (line 10) | class VisConnector : public QObject {
  function class (line 52) | class Server : public QObject

FILE: MiniZincIDE/server/connector.js
  function resolveResponse (line 27) | function resolveResponse(index, payload) {
  function rejectResponse (line 34) | function rejectResponse(index, message) {
  function createPromise (line 41) | function createPromise(message) {
  function on (line 52) | function on(event, callback) {
  function off (line 58) | function off(event, callback) {
  function getUserData (line 63) | function getUserData() {
  function goToSolution (line 75) | function goToSolution(idx) {
  function solve (line 84) | function solve(modelFile, dataFiles, options) {
  function getNumSolutions (line 92) | function getNumSolutions() {
  function getSolution (line 97) | function getSolution(index) {
  function getAllSolutions (line 103) | function getAllSolutions() {
  function getStatus (line 108) | function getStatus() {
  function getFinishTime (line 113) | function getFinishTime() {

FILE: MiniZincIDE/solver.cpp
  function parseArgList (line 13) | void parseArgList(const QString& s, QVariantMap& map) {
  function Solver (line 226) | Solver& Solver::lookup(const QString& str)
  function Solver (line 249) | Solver& Solver::lookup(const QString& id, const QString& version, bool s...
  function SolverConfiguration (line 300) | SolverConfiguration SolverConfiguration::loadJSON(const QString& filenam...
  function SolverConfiguration (line 327) | SolverConfiguration SolverConfiguration::loadJSON(const QJsonDocument& j...
  function SolverConfiguration (line 429) | SolverConfiguration SolverConfiguration::loadLegacy(const QJsonDocument ...
  function QString (line 516) | QString SolverConfiguration::name() const
  function QByteArray (line 539) | QByteArray SolverConfiguration::toJSON(void) const
  function QJsonObject (line 546) | QJsonObject SolverConfiguration::toJSONObject(void) const

FILE: MiniZincIDE/solver.h
  type SolverFlag (line 10) | struct SolverFlag {
  function Solver (line 22) | Q_DECLARE_METATYPE(SolverFlag)
  function class (line 69) | class SolverConfiguration {

FILE: MiniZincIDE/theme.cpp
  function QString (line 3) | QString Theme::styleSheet(bool darkMode) const

FILE: MiniZincIDE/theme.h
  function ThemeColor (line 8) | struct ThemeColor
  function QColor (line 23) | QColor get(bool darkMode) const {
  type Theme (line 28) | struct Theme
  function class (line 85) | class ThemeManager : public QObject

FILE: cp-profiler/src/cpp-integration/connector.hpp
  type cpprofiler (line 29) | namespace cpprofiler {
    class Option (line 32) | class Option {
      method valid (line 37) | bool valid() const { return present; }
      method set (line 38) | void set(const T& t) { present = true; value_ = t; }
      method unset (line 39) | void unset() { present = false; }
      method T (line 40) | const T& value() const { assert(present); return value_; }
      method T (line 41) | T& value() { assert(present); return value_; }
    class Connector (line 44) | class Connector
      method sendOverSocket (line 141) | void sendOverSocket() {
      method sendRawMsg (line 150) | void sendRawMsg(const std::vector<char>& buf) {
      method Connector (line 158) | Connector(unsigned int port) : port(port), _connected(false) {}
      method connected (line 160) | bool connected() { return _connected; }
      method connect (line 164) | void connect() {
      method start (line 224) | void start(const std::string& file_path = "",
      method restart (line 252) | void restart(int restart_id = -1) {
      method done (line 267) | void done() {
      method disconnect (line 273) | void disconnect() {
      method sendNode (line 281) | void sendNode(const Node& node) {
      method Node (line 294) | Node createNode(NodeUID node, NodeUID parent,
    class Node (line 45) | class Node
      method Node (line 63) | Node(NodeUID node, NodeUID parent,
      method Node (line 68) | Node& set_node_thread_id(int tid) {
      method Node (line 75) | Node& set_label(const std::string& label) {
      method Node (line 82) | Node& set_nogood(const std::string& nogood) {
      method Node (line 89) | Node& set_info(const std::string& info) {
      method alt (line 94) | int alt() const { return alt_; }
      method kids (line 95) | int kids() const { return kids_; }
      method NodeStatus (line 97) | NodeStatus status() const { return status_; }
      method NodeUID (line 99) | NodeUID nodeUID() const { return node_; }
      method NodeUID (line 100) | NodeUID parentUID() const { return parent_; }
      method node_id (line 102) | int node_id() const { return node_.nid; }
      method parent_id (line 103) | int parent_id() const { return parent_.nid; }
      method node_thread_id (line 104) | int node_thread_id() const {  return node_.tid; }
      method node_restart_id (line 105) | int node_restart_id() const { return node_.rid; }
      method parent_thread_id (line 106) | int parent_thread_id() const {  return parent_.tid; }
      method parent_restart_id (line 107) | int parent_restart_id() const { return parent_.rid; }
      method send (line 109) | void send() { sendNode(_c, *this); }
    class Node (line 48) | class Node {
      method Node (line 63) | Node(NodeUID node, NodeUID parent,
      method Node (line 68) | Node& set_node_thread_id(int tid) {
      method Node (line 75) | Node& set_label(const std::string& label) {
      method Node (line 82) | Node& set_nogood(const std::string& nogood) {
      method Node (line 89) | Node& set_info(const std::string& info) {
      method alt (line 94) | int alt() const { return alt_; }
      method kids (line 95) | int kids() const { return kids_; }
      method NodeStatus (line 97) | NodeStatus status() const { return status_; }
      method NodeUID (line 99) | NodeUID nodeUID() const { return node_; }
      method NodeUID (line 100) | NodeUID parentUID() const { return parent_; }
      method node_id (line 102) | int node_id() const { return node_.nid; }
      method parent_id (line 103) | int parent_id() const { return parent_.nid; }
      method node_thread_id (line 104) | int node_thread_id() const {  return node_.tid; }
      method node_restart_id (line 105) | int node_restart_id() const { return node_.rid; }
      method parent_thread_id (line 106) | int parent_thread_id() const {  return parent_.tid; }
      method parent_restart_id (line 107) | int parent_restart_id() const { return parent_.rid; }
      method send (line 109) | void send() { sendNode(_c, *this); }
    function sendall (line 113) | static int sendall(int s, const char* buf, int* len) {
    class Connector (line 132) | class Connector {
      method sendOverSocket (line 141) | void sendOverSocket() {
      method sendRawMsg (line 150) | void sendRawMsg(const std::vector<char>& buf) {
      method Connector (line 158) | Connector(unsigned int port) : port(port), _connected(false) {}
      method connected (line 160) | bool connected() { return _connected; }
      method connect (line 164) | void connect() {
      method start (line 224) | void start(const std::string& file_path = "",
      method restart (line 252) | void restart(int restart_id = -1) {
      method done (line 267) | void done() {
      method disconnect (line 273) | void disconnect() {
      method sendNode (line 281) | void sendNode(const Node& node) {
      method Node (line 294) | Node createNode(NodeUID node, NodeUID parent,
    function sendNode (line 300) | void sendNode(Connector& c, Node& node) { c.sendNode(node); }

FILE: cp-profiler/src/cpp-integration/message.hpp
  type cpprofiler (line 9) | namespace cpprofiler {
    type NodeStatus (line 13) | enum NodeStatus {
    type MsgType (line 20) | enum class MsgType {
    type NodeUID (line 28) | struct NodeUID {
    class Message (line 38) | class Message {
      method isNode (line 60) | bool isNode(void) const { return _type == MsgType::NODE; }
      method isDone (line 61) | bool isDone(void) const { return _type == MsgType::DONE; }
      method isStart (line 62) | bool isStart(void) const { return _type == MsgType::START; }
      method isRestart (line 63) | bool isRestart(void) const { return _type == MsgType::RESTART; }
      method NodeUID (line 65) | NodeUID nodeUID(void) const { return _node; }
      method set_nodeUID (line 66) | void set_nodeUID(const NodeUID& n) { _node = n; }
      method NodeUID (line 68) | NodeUID parentUID(void) const { return _parent; }
      method set_parentUID (line 69) | void set_parentUID(const NodeUID& p) { _parent = p; }
      method alt (line 71) | int32_t alt(void) const { return _alt; }
      method set_alt (line 72) | void set_alt(int32_t alt) { _alt = alt; }
      method kids (line 74) | int32_t kids(void) const { return _kids; }
      method set_kids (line 75) | void set_kids(int32_t kids) { _kids = kids; }
      method NodeStatus (line 77) | NodeStatus status(void) const { return _status; }
      method set_status (line 78) | void set_status(NodeStatus status) { _status = status; }
      method set_label (line 80) | void set_label(const std::string& label) {
      method set_info (line 85) | void set_info(const std::string& info) {
      method set_nogood (line 90) | void set_nogood(const std::string& nogood) {
      method set_version (line 95) | void set_version(int32_t v) {
      method has_version (line 100) | bool has_version(void) const { return _have_version; }
      method version (line 101) | int32_t version(void) const { return _version; }
      method has_label (line 103) | bool has_label(void) const { return _have_label; }
      method has_nogood (line 106) | bool has_nogood(void) const { return _have_nogood; }
      method has_info (line 110) | bool has_info(void) const { return _have_info; }
      method set_type (line 113) | void set_type(MsgType type) { _type = type; }
      method MsgType (line 114) | MsgType type(void) const { return _type; }
      method reset (line 116) | void reset(void) {
    class MessageMarshalling (line 125) | class MessageMarshalling {
      type Field (line 129) | enum Field {
      method serializeType (line 140) | static void serializeType(std::vector<char>& data, MsgType f) {
      method serializeField (line 144) | static void serializeField(std::vector<char>& data, Field f) {
      method serialize (line 148) | static void serialize(std::vector<char>& data, int32_t i) {
      method serialize (line 155) | static void serialize(std::vector<char>& data, NodeStatus s) {
      method serialize (line 159) | static void serialize(std::vector<char>& data, const std::string& s) {
      method MsgType (line 166) | static MsgType deserializeMsgType(iter& it) {
      method Field (line 172) | static Field deserializeField(iter& it) {
      method deserializeInt (line 178) | static int32_t deserializeInt(iter& it) {
      method NodeStatus (line 187) | static NodeStatus deserializeStatus(iter& it) {
      method deserializeString (line 193) | static std::string deserializeString(iter& it) {
      method Message (line 205) | Message& makeNode(NodeUID node, NodeUID parent,
      method makeStart (line 220) | void makeStart(const std::string& info) {
      method makeRestart (line 227) | void makeRestart(const std::string& info) {
      method makeDone (line 233) | void makeDone(void) {
      method Message (line 238) | const Message& get_msg(void) { return msg; }
      method serialize (line 240) | std::vector<char> serialize(void) const {
      method deserialize (line 285) | void deserialize(char* data, size_t size) {

FILE: cp-profiler/src/cpprofiler/analysis/histogram_scene.cpp
  type cpprofiler (line 5) | namespace cpprofiler
    type analysis (line 7) | namespace analysis
      type Align (line 16) | enum class Align
      function addText (line 25) | static void addText(QGraphicsScene &scene, int col, int row,
      function addRect (line 53) | static std::shared_ptr<PatternRect> addRect(HistogramScene &hist_sce...
      function addText (line 67) | static void addText(QGraphicsScene &scene, int col, int row, const c...
      function addText (line 73) | static void addText(QGraphicsScene &scene, int col, int row, int value)
      function PatternPtr (line 149) | PatternPtr HistogramScene::rectToPattern(PatternRectPtr prect) const

FILE: cp-profiler/src/cpprofiler/analysis/histogram_scene.hh
  type cpprofiler (line 12) | namespace cpprofiler
    type analysis (line 14) | namespace analysis
      class PatternRect (line 20) | class PatternRect
      type PatternProp (line 21) | enum class PatternProp
      class HistogramScene (line 26) | class HistogramScene : public QObject
        method HistogramScene (line 55) | HistogramScene()
        method QGraphicsScene (line 64) | QGraphicsScene *scene()

FILE: cp-profiler/src/cpprofiler/analysis/merge_window.cpp
  type cpprofiler (line 21) | namespace cpprofiler
    type analysis (line 23) | namespace analysis
      function linkLocationsPentagon (line 198) | static void linkLocationsPentagon(NodeID n_m,
      function MergeResult (line 282) | MergeResult &MergeWindow::mergeResult()
      type ng_analysis (line 287) | namespace ng_analysis
        type ReductionStats (line 290) | struct ReductionStats
        class ResultBuilder (line 296) | class ResultBuilder
          method ResultBuilder (line 305) | ResultBuilder() {}
          method addPentagonData (line 308) | void addPentagonData(
          method ResType (line 329) | const ResType &result() const { return ng_items; }
      function has_as_ancestor (line 416) | static bool has_as_ancestor(const tree::NodeTree &nt, NodeID n, Node...
      function under_pentagon (line 430) | static bool under_pentagon(const tree::NodeTree &nt, NodeID n)

FILE: cp-profiler/src/cpprofiler/analysis/merge_window.hh
  type cpprofiler (line 7) | namespace cpprofiler
    type tree (line 9) | namespace tree
      class TraditionalView (line 11) | class TraditionalView
    class Execution (line 14) | class Execution
    class UserData (line 15) | class UserData
    type analysis (line 20) | namespace analysis
      class PentagonCounter (line 23) | class PentagonCounter
      class PentagonListWidget (line 24) | class PentagonListWidget
      type OriginalLoc (line 27) | struct OriginalLoc
      class MergeWindow (line 32) | class MergeWindow : public QMainWindow
  type cpprofiler (line 18) | namespace cpprofiler
    type tree (line 9) | namespace tree
      class TraditionalView (line 11) | class TraditionalView
    class Execution (line 14) | class Execution
    class UserData (line 15) | class UserData
    type analysis (line 20) | namespace analysis
      class PentagonCounter (line 23) | class PentagonCounter
      class PentagonListWidget (line 24) | class PentagonListWidget
      type OriginalLoc (line 27) | struct OriginalLoc
      class MergeWindow (line 32) | class MergeWindow : public QMainWindow

FILE: cp-profiler/src/cpprofiler/analysis/merging/merge_result.hh
  type cpprofiler (line 6) | namespace cpprofiler
    type analysis (line 8) | namespace analysis
      type PentagonItem (line 11) | struct PentagonItem

FILE: cp-profiler/src/cpprofiler/analysis/merging/pentagon_list_widget.hh
  type cpprofiler (line 11) | namespace cpprofiler
    type analysis (line 13) | namespace analysis
      class PentagonListWidget (line 16) | class PentagonListWidget : public QWidget
        method viewWidth (line 41) | int viewWidth() { return view_->viewport()->width(); }
        method handleClick (line 44) | void handleClick(NodeID node)
        method handleSortCB (line 57) | void handleSortCB(int state)

FILE: cp-profiler/src/cpprofiler/analysis/merging/pentagon_rect.cpp
  type cpprofiler (line 9) | namespace cpprofiler
    type analysis (line 11) | namespace analysis

FILE: cp-profiler/src/cpprofiler/analysis/merging/pentagon_rect.hh
  type cpprofiler (line 6) | namespace cpprofiler
    type analysis (line 8) | namespace analysis
      class PentagonListWidget (line 11) | class PentagonListWidget
      type PentagonItem (line 12) | struct PentagonItem
      type pent_config (line 14) | namespace pent_config
      class PentagonRect (line 31) | class PentagonRect : public QGraphicsRectItem

FILE: cp-profiler/src/cpprofiler/analysis/nogood_analysis_dialog.hh
  type cpprofiler (line 18) | namespace cpprofiler
    type analysis (line 21) | namespace analysis
      type NgAnalysisItem (line 24) | struct NgAnalysisItem
      class NogoodProxyModel (line 35) | class NogoodProxyModel : public QSortFilterProxyModel
        method lessThan (line 38) | bool lessThan(const QModelIndex &left, const QModelIndex &right) c...
      class NogoodAnalysisDialog (line 48) | class NogoodAnalysisDialog : public QDialog
        method init (line 59) | void init()
        method saveNogoods (line 99) | void saveNogoods()
        method NogoodAnalysisDialog (line 137) | NogoodAnalysisDialog(NgAnalysisData nga_data) : QDialog(), ng_data...
        method populate (line 145) | void populate(const NgAnalysisData &nga_data)

FILE: cp-profiler/src/cpprofiler/analysis/path_comp.cpp
  type cpprofiler (line 6) | namespace cpprofiler
    type analysis (line 8) | namespace analysis
      function set_intersect (line 12) | static vector<Label> set_intersect(vector<Label> v1, vector<Label> v2)
      function set_symmetric_diff (line 29) | static vector<Label> set_symmetric_diff(vector<Label> v1, vector<Lab...
      function getLabelDiff (line 47) | std::pair<vector<Label>, vector<Label>>

FILE: cp-profiler/src/cpprofiler/analysis/path_comp.hh
  type cpprofiler (line 7) | namespace cpprofiler
    type analysis (line 9) | namespace analysis

FILE: cp-profiler/src/cpprofiler/analysis/pattern_rect.cpp
  type cpprofiler (line 4) | namespace cpprofiler
    type analysis (line 6) | namespace analysis

FILE: cp-profiler/src/cpprofiler/analysis/pattern_rect.hh
  type cpprofiler (line 7) | namespace cpprofiler
    type analysis (line 9) | namespace analysis
      class HistogramScene (line 12) | class HistogramScene
      class PatternRect (line 14) | class PatternRect : public QGraphicsRectItem

FILE: cp-profiler/src/cpprofiler/analysis/pentagon_counter.hpp
  type cpprofiler (line 6) | namespace cpprofiler
    type analysis (line 8) | namespace analysis
      class PentagonCounter (line 11) | class PentagonCounter : public QWidget
        method PentagonCounter (line 17) | PentagonCounter(QWidget *parent) : QWidget(parent)
        method update (line 30) | void update(int count)

FILE: cp-profiler/src/cpprofiler/analysis/similar_subtree_analysis.cpp
  type cpprofiler (line 12) | namespace cpprofiler
    type analysis (line 15) | namespace analysis
      type ShapeInfo (line 24) | struct ShapeInfo
      type CompareShapes (line 30) | struct CompareShapes
      function set_as_processed (line 59) | static void set_as_processed(const NodeTree &nt, Partition &partitio...
      function separate_marked (line 80) | static vector<Group> separate_marked(const vector<Group> &rem_groups...
      function partition_step (line 118) | static void partition_step(const NodeTree &nt, Partition &p, int h, ...
      function Partition (line 158) | static Partition initialPartition(const NodeTree &nt)
      function calculateHeightOf (line 217) | static int calculateHeightOf(NodeID nid, const NodeTree &nt, vector<...
      function runIdenticalSubtrees (line 244) | vector<SubtreePattern> runIdenticalSubtrees(const NodeTree &nt)
      function runSimilarShapes (line 301) | std::vector<SubtreePattern> runSimilarShapes(const NodeTree &tree, c...

FILE: cp-profiler/src/cpprofiler/analysis/similar_subtree_analysis.hh
  type cpprofiler (line 7) | namespace cpprofiler
    type tree (line 10) | namespace tree
      class NodeTree (line 12) | class NodeTree
      class Layout (line 13) | class Layout
    type analysis (line 16) | namespace analysis
      type Partition (line 21) | struct Partition
        method Partition (line 27) | Partition(std::vector<Group> &&proc, std::vector<Group> &&rem)
      type LabelOption (line 33) | enum class LabelOption
      type SubtreePattern (line 40) | struct SubtreePattern

FILE: cp-profiler/src/cpprofiler/analysis/similar_subtree_window.cpp
  type cpprofiler (line 35) | namespace cpprofiler
    type analysis (line 37) | namespace analysis
      function PatternProp (line 59) | static PatternProp str2Prop(const QString &str)
      function QString (line 73) | static QString prop2str(PatternProp prop)
      function eliminateSubsumed (line 296) | static vector<SubtreePattern> eliminateSubsumed(const NodeTree &tree,
      function computeShapes (line 344) | static std::unique_ptr<tree::Layout> computeShapes(const NodeTree &t...
      function labelPath (line 451) | static std::vector<Label> labelPath(NodeID nid, const tree::NodeTree...

FILE: cp-profiler/src/cpprofiler/analysis/similar_subtree_window.hh
  class QGraphicsScene (line 12) | class QGraphicsScene
  type cpprofiler (line 14) | namespace cpprofiler
    type tree (line 16) | namespace tree
      class NodeTree (line 18) | class NodeTree
      class Layout (line 19) | class Layout
      class SubtreeView (line 20) | class SubtreeView
    type analysis (line 26) | namespace analysis
      type SubtreePattern (line 29) | struct SubtreePattern
      type SimilarityType (line 31) | enum class SimilarityType
      class HistogramScene (line 37) | class HistogramScene
      class PathDiffLine (line 40) | class PathDiffLine : public QLineEdit
        method PathDiffLine (line 43) | PathDiffLine() : QLineEdit()
      type defaults (line 49) | namespace defaults
      type ss_analysis (line 57) | namespace ss_analysis
      class SimilarSubtreeWindow (line 62) | class SimilarSubtreeWindow : public QDialog
        type SubtreeAnalysisFilters (line 82) | struct SubtreeAnalysisFilters
        type Settings (line 88) | struct Settings
  type cpprofiler (line 24) | namespace cpprofiler
    type tree (line 16) | namespace tree
      class NodeTree (line 18) | class NodeTree
      class Layout (line 19) | class Layout
      class SubtreeView (line 20) | class SubtreeView
    type analysis (line 26) | namespace analysis
      type SubtreePattern (line 29) | struct SubtreePattern
      type SimilarityType (line 31) | enum class SimilarityType
      class HistogramScene (line 37) | class HistogramScene
      class PathDiffLine (line 40) | class PathDiffLine : public QLineEdit
        method PathDiffLine (line 43) | PathDiffLine() : QLineEdit()
      type defaults (line 49) | namespace defaults
      type ss_analysis (line 57) | namespace ss_analysis
      class SimilarSubtreeWindow (line 62) | class SimilarSubtreeWindow : public QDialog
        type SubtreeAnalysisFilters (line 82) | struct SubtreeAnalysisFilters
        type Settings (line 88) | struct Settings

FILE: cp-profiler/src/cpprofiler/analysis/subtree_pattern.hh
  type cpprofiler (line 4) | namespace cpprofiler
    type analysis (line 6) | namespace analysis
      type PatternProp (line 10) | enum class PatternProp
      type SubtreePattern (line 17) | struct SubtreePattern
        method SubtreePattern (line 27) | explicit SubtreePattern(int height) : m_height(height)
        method SubtreePattern (line 31) | SubtreePattern() = default;
        method setSize (line 33) | void setSize(int size)
        method size (line 38) | int size() const
        method count (line 43) | int count() const
        method height (line 48) | int height() const
        method NodeID (line 53) | NodeID first() const

FILE: cp-profiler/src/cpprofiler/analysis/tree_merger.cpp
  type cpprofiler (line 11) | namespace cpprofiler
    type analysis (line 13) | namespace analysis
      function find_and_replace_all (line 38) | static void find_and_replace_all(std::string &str, std::string subst...
      function labelsEqual (line 48) | static bool labelsEqual(std::string lhs, std::string rhs)
      function compareNodes (line 82) | static bool compareNodes(NodeID n1, const NodeTree &nt1,
      function copy_tree_into (line 105) | static void copy_tree_into(NodeTree &nt, NodeID nid, const NodeTree ...
      function create_pentagon (line 134) | void create_pentagon(NodeTree &nt, NodeID nid,

FILE: cp-profiler/src/cpprofiler/analysis/tree_merger.hh
  type cpprofiler (line 8) | namespace cpprofiler
    type tree (line 11) | namespace tree
      class NodeTree (line 13) | class NodeTree
    class Execution (line 16) | class Execution
    type analysis (line 21) | namespace analysis
      type OriginalLoc (line 24) | struct OriginalLoc
      class TreeMerger (line 26) | class TreeMerger : public QThread
  type cpprofiler (line 19) | namespace cpprofiler
    type tree (line 11) | namespace tree
      class NodeTree (line 13) | class NodeTree
    class Execution (line 16) | class Execution
    type analysis (line 21) | namespace analysis
      type OriginalLoc (line 24) | struct OriginalLoc
      class TreeMerger (line 26) | class TreeMerger : public QThread

FILE: cp-profiler/src/cpprofiler/command_line_parser.cpp
  type cpprofiler (line 4) | namespace cpprofiler
    type cl_options (line 7) | namespace cl_options
    function QString (line 34) | QString CommandLineParser::value(const QCommandLineOption &opt)

FILE: cp-profiler/src/cpprofiler/command_line_parser.hh
  type cpprofiler (line 6) | namespace cpprofiler
    type cl_options (line 9) | namespace cl_options
    class CommandLineParser (line 19) | class CommandLineParser

FILE: cp-profiler/src/cpprofiler/conductor.cpp
  type cpprofiler (line 41) | namespace cpprofiler
    function getRandomExID (line 160) | static int getRandomExID()
    function Execution (line 302) | Execution *Conductor::addNewExecution(const std::string &ex_name, int ...
    function Execution (line 327) | Execution* Conductor::getExecution(int exec_id)
    function ExecutionWindow (line 336) | ExecutionWindow &Conductor::getExecutionWindow(Execution *e)
    function getHeatMapUrl (line 536) | static std::string getHeatMapUrl(const NameMap &nm,
  type cpprofiler (line 662) | namespace cpprofiler
    function getRandomExID (line 160) | static int getRandomExID()
    function Execution (line 302) | Execution *Conductor::addNewExecution(const std::string &ex_name, int ...
    function Execution (line 327) | Execution* Conductor::getExecution(int exec_id)
    function ExecutionWindow (line 336) | ExecutionWindow &Conductor::getExecutionWindow(Execution *e)
    function getHeatMapUrl (line 536) | static std::string getHeatMapUrl(const NameMap &nm,

FILE: cp-profiler/src/cpprofiler/conductor.hh
  type cpprofiler (line 14) | namespace cpprofiler
    type analysis (line 17) | namespace analysis
      class MergeWindow (line 19) | class MergeWindow
    class TcpServer (line 22) | class TcpServer
    class Execution (line 23) | class Execution
    class ExecutionList (line 24) | class ExecutionList
    class ExecutionWindow (line 25) | class ExecutionWindow
    class ReceiverThread (line 26) | class ReceiverThread
    class TreeBuilder (line 27) | class TreeBuilder
    class NameMap (line 28) | class NameMap
    type ExecMeta (line 30) | struct ExecMeta
    class Conductor (line 37) | class Conductor : public QMainWindow

FILE: cp-profiler/src/cpprofiler/config.hh
  type cpprofiler (line 5) | namespace cpprofiler
    type tree (line 7) | namespace tree
      type layout (line 10) | namespace layout
      type traditional (line 16) | namespace traditional
      type lantern (line 58) | namespace lantern

FILE: cp-profiler/src/cpprofiler/core.cpp
  type cpprofiler (line 3) | namespace cpprofiler
    type tree (line 5) | namespace tree
  type cpprofiler (line 54) | namespace cpprofiler
    type tree (line 5) | namespace tree

FILE: cp-profiler/src/cpprofiler/core.hh
  type cpprofiler (line 16) | namespace cpprofiler
    type tree (line 18) | namespace tree
      type NodeStatus (line 21) | enum class NodeStatus
    class Nogood (line 41) | class Nogood
      method Nogood (line 51) | explicit Nogood(const std::string &orig) : renamed_(false), orig_ng_...
      method Nogood (line 53) | Nogood(const std::string &orig, const std::string &renamed) : rename...
      method has_renamed (line 60) | bool has_renamed() const { return renamed_; }
  type cpprofiler (line 36) | namespace cpprofiler
    type tree (line 18) | namespace tree
      type NodeStatus (line 21) | enum class NodeStatus
    class Nogood (line 41) | class Nogood
      method Nogood (line 51) | explicit Nogood(const std::string &orig) : renamed_(false), orig_ng_...
      method Nogood (line 53) | Nogood(const std::string &orig, const std::string &renamed) : rename...
      method has_renamed (line 60) | bool has_renamed() const { return renamed_; }

FILE: cp-profiler/src/cpprofiler/db_handler.cpp
  type cpprofiler (line 11) | namespace cpprofiler
    type db_handler (line 13) | namespace db_handler
      type NodeData (line 18) | struct NodeData
      type BookmarkItem (line 28) | struct BookmarkItem
      type NogoodItem (line 34) | struct NogoodItem
      type InfoItem (line 40) | struct InfoItem
      function count_nodes (line 46) | static int count_nodes(QSqlDatabase *db)
      function read_nodes (line 57) | static bool read_nodes(QSqlDatabase *db, Execution &ex)
      function read_bookmarks (line 98) | static bool read_bookmarks(QSqlDatabase *db, Execution &ex)
      function read_info (line 121) | static bool read_info(QSqlDatabase *db, Execution &ex)
      function read_nogoods (line 144) | static bool read_nogoods(QSqlDatabase *db, Execution &ex)
      function insert_node (line 165) | static void insert_node(QSqlQuery *stmt, NodeData nd)
      function save_nodes (line 182) | static void save_nodes(QSqlDatabase *db, const Execution *ex)
      function insert_bookmark (line 217) | static void insert_bookmark(QSqlQuery *stmt, BookmarkItem bi)
      function insert_nogood (line 230) | static void insert_nogood(QSqlQuery *stmt, NogoodItem ngi)
      function save_nogoods (line 244) | static void save_nogoods(QSqlDatabase *db, const Execution *ex)
      function insert_info (line 273) | static void insert_info(QSqlQuery *stmt, InfoItem ii)
      function save_info (line 286) | static void save_info(QSqlDatabase *db, const Execution *ex)
      function save_user_data (line 312) | static void save_user_data(QSqlDatabase *db, const Execution *ex)
      function create_db (line 336) | static bool create_db(QSqlDatabase* db)
      function save_execution (line 373) | void save_execution(const Execution *ex, const char *path)
      function load_execution (line 413) | std::shared_ptr<Execution> load_execution(const char *path, ExecID eid)

FILE: cp-profiler/src/cpprofiler/db_handler.hh
  type cpprofiler (line 5) | namespace cpprofiler
    class Execution (line 8) | class Execution
    type db_handler (line 10) | namespace db_handler

FILE: cp-profiler/src/cpprofiler/execution.cpp
  type cpprofiler (line 10) | namespace cpprofiler

FILE: cp-profiler/src/cpprofiler/execution.hh
  type cpprofiler (line 13) | namespace cpprofiler
    class Execution (line 16) | class Execution
      method ExecID (line 37) | ExecID id() { return id_; }
      method SolverData (line 43) | SolverData &solver_data() { return *solver_data_; }
      method SolverData (line 44) | const SolverData &solver_data() const { return *solver_data_; }
      method UserData (line 46) | inline UserData &userData() { return *user_data_; }
      method UserData (line 47) | inline const UserData &userData() const { return *user_data_; }
      method hasNogoods (line 52) | bool hasNogoods() const { return solver_data_->hasNogoods(); }
      method NameMap (line 54) | const NameMap *nameMap() const { return name_map_.get(); }

FILE: cp-profiler/src/cpprofiler/execution_list.cpp
  type cpprofiler (line 7) | namespace cpprofiler
    function Execution (line 13) | Execution *ExecutionItem::get_execution()
  type cpprofiler (line 19) | namespace cpprofiler
    function Execution (line 13) | Execution *ExecutionItem::get_execution()

FILE: cp-profiler/src/cpprofiler/execution_list.hh
  type cpprofiler (line 9) | namespace cpprofiler
    class Execution (line 12) | class Execution
    class ExecutionItem (line 14) | class ExecutionItem : public QStandardItem
    class ExecutionList (line 23) | class ExecutionList
      method QWidget (line 32) | QWidget *getWidget() { return &m_tree_view; }

FILE: cp-profiler/src/cpprofiler/execution_window.cpp
  type cpprofiler (line 35) | namespace cpprofiler
    function writeToFile (line 440) | static void writeToFile(const QString &path, const QString &str)

FILE: cp-profiler/src/cpprofiler/execution_window.hh
  type cpprofiler (line 11) | namespace cpprofiler
    type utils (line 14) | namespace utils
      class MaybeCaller (line 16) | class MaybeCaller
    type tree (line 19) | namespace tree
      class TraditionalView (line 21) | class TraditionalView
    type pixel_view (line 24) | namespace pixel_view
      class PtCanvas (line 26) | class PtCanvas
      class IcicleCanvas (line 27) | class IcicleCanvas
    class Execution (line 30) | class Execution
    class LanternMenu (line 32) | class LanternMenu : public QWidget
      method value (line 43) | int value() { return slider_->value(); }
      method setMax (line 46) | void setMax(int v) { slider_->setMaximum(v); }
    class ExecutionWindow (line 53) | class ExecutionWindow : public QMainWindow
      method Execution (line 86) | Execution& execution()

FILE: cp-profiler/src/cpprofiler/message_wrapper.hh
  type cpprofiler (line 9) | namespace cpprofiler {
    class MessageWrapper (line 15) | class MessageWrapper
      method MessageWrapper (line 18) | MessageWrapper() = default;
      method MessageWrapper (line 19) | MessageWrapper(const MessageWrapper &other) = default;
      method MessageWrapper (line 22) | MessageWrapper(const Message& msg): _msg(msg) {}
      method Message (line 24) | Message& msg() { return _msg; }
      method Message (line 25) | const Message& msg() const { return _msg; }

FILE: cp-profiler/src/cpprofiler/name_map.cpp
  type cpprofiler (line 17) | namespace cpprofiler
    function read_file_by_lines (line 23) | static vector<string> read_file_by_lines(const string &file)
    function getLocation (line 51) | static std::pair<Location, bool> getLocation(const string &path)
    function Location (line 90) | static const Location &findLocation(const SymbolTable &st,
    function string (line 101) | static const string findPath(const SymbolTable &st, const string &ident)
    function string (line 111) | static string extractExpression(const vector<string> &model,
    function string (line 118) | static string getPathUntilDecomp(const string &path)
    type TElem (line 128) | struct TElem
    function NiceName (line 281) | const NiceName &NameMap::getNiceName(const std::string &ident) const
    function Path (line 292) | const Path &NameMap::getPath(const std::string &ident) const

FILE: cp-profiler/src/cpprofiler/name_map.hh
  type cpprofiler (line 15) | namespace cpprofiler
    type Location (line 18) | struct Location
      method Location (line 24) | Location() = default;
      method Location (line 25) | Location(int sl_, int sc_, int el_, int ec_) : sl(sl_), sc(sc_), el(...
    type SymbolRecord (line 28) | struct SymbolRecord
      method SymbolRecord (line 35) | SymbolRecord() = default;
      method SymbolRecord (line 36) | SymbolRecord(const std::string &nname, const std::string &p, const L...
    class NameMap (line 46) | class NameMap

FILE: cp-profiler/src/cpprofiler/nogood_dialog.cpp
  type cpprofiler (line 10) | namespace cpprofiler

FILE: cp-profiler/src/cpprofiler/nogood_dialog.hh
  type cpprofiler (line 7) | namespace cpprofiler
    type tree (line 10) | namespace tree
      class NodeTree (line 12) | class NodeTree
    class NogoodDialog (line 15) | class NogoodDialog : public QDialog

FILE: cp-profiler/src/cpprofiler/options.hh
  type cpprofiler (line 3) | namespace cpprofiler
    type Options (line 6) | struct Options

FILE: cp-profiler/src/cpprofiler/pixel_views/icicle_canvas.cpp
  type cpprofiler (line 16) | namespace cpprofiler
    type pixel_view (line 19) | namespace pixel_view
      type colors (line 22) | namespace colors
      class IcicleLayout (line 30) | class IcicleLayout
        method resize (line 38) | void resize(size_t n)
        method width (line 44) | inline int width(NodeID n) const { return width_[n]; }
        method setWidth (line 45) | inline void setWidth(NodeID n, int v) { width_[n] = v; }
        method hasSol (line 47) | inline bool hasSol(NodeID n) const { return has_sol[n]; }
        method setHasSol (line 48) | inline void setHasSol(NodeID n, bool v) { has_sol[n] = v; }
      function computeLayout (line 51) | static std::unique_ptr<IcicleLayout> computeLayout(const tree::NodeT...
      function NodeID (line 127) | static NodeID findNode(const tree::NodeTree &nt, const IcicleLayout ...
      class IcicleDrawing (line 296) | class IcicleDrawing
        method QRgb (line 311) | QRgb getColor(NodeID n)
        method drawIcicleSubtree (line 338) | void drawIcicleSubtree(NodeID n, int cur_x, int cur_y)
        method IcicleDrawing (line 371) | IcicleDrawing(const tree::NodeTree &nt, IcicleLayout &lo, PixelIma...
        method run (line 381) | void run(NodeID root, int x, int y)

FILE: cp-profiler/src/cpprofiler/pixel_views/icicle_canvas.hh
  type cpprofiler (line 8) | namespace cpprofiler
    type utils (line 11) | namespace utils
      class MaybeCaller (line 13) | class MaybeCaller
    type tree (line 16) | namespace tree
      class NodeTree (line 18) | class NodeTree
    type pixel_view (line 21) | namespace pixel_view
      class PixelImage (line 24) | class PixelImage
      class PixelWidget (line 25) | class PixelWidget
      class IcicleLayout (line 26) | class IcicleLayout
      class IcicleCanvas (line 28) | class IcicleCanvas : public QWidget

FILE: cp-profiler/src/cpprofiler/pixel_views/pixel_image.cpp
  type cpprofiler (line 8) | namespace cpprofiler
    type pixel_view (line 11) | namespace pixel_view

FILE: cp-profiler/src/cpprofiler/pixel_views/pixel_image.hh
  class QImage (line 10) | class QImage
  type cpprofiler (line 12) | namespace cpprofiler
    type pixel_view (line 15) | namespace pixel_view
      class PixelImage (line 20) | class PixelImage : public QObject
        method QImage (line 55) | const QImage &raw_image() const
        method setPixelSize (line 60) | void setPixelSize(int size) { pixel_size_ = size; }
        method pixel_size (line 62) | int pixel_size() const { return pixel_size_; }
        method setDarkMode (line 64) | void setDarkMode(bool d) { dark_mode_ = d; }

FILE: cp-profiler/src/cpprofiler/pixel_views/pixel_item.hh
  type cpprofiler (line 4) | namespace cpprofiler
    type pixel_view (line 7) | namespace pixel_view

FILE: cp-profiler/src/cpprofiler/pixel_views/pixel_widget.cpp
  type cpprofiler (line 5) | namespace cpprofiler
    type pixel_view (line 8) | namespace pixel_view

FILE: cp-profiler/src/cpprofiler/pixel_views/pixel_widget.hh
  type cpprofiler (line 12) | namespace cpprofiler
    type pixel_view (line 15) | namespace pixel_view
      class PixelWidget (line 18) | class PixelWidget : public QAbstractScrollArea
        method paintEvent (line 29) | void paintEvent(QPaintEvent *) override
        method resizeEvent (line 35) | void resizeEvent(QResizeEvent *e) override
        method PixelWidget (line 45) | PixelWidget(const PixelImage &image) : image_(image) {}
        method width (line 48) | int width() const

FILE: cp-profiler/src/cpprofiler/pixel_views/pt_canvas.cpp
  type cpprofiler (line 17) | namespace cpprofiler
    type pixel_view (line 20) | namespace pixel_view
      type colors (line 23) | namespace colors

FILE: cp-profiler/src/cpprofiler/pixel_views/pt_canvas.hh
  type cpprofiler (line 13) | namespace cpprofiler
    type tree (line 16) | namespace tree
      class NodeTree (line 18) | class NodeTree
    type pixel_view (line 21) | namespace pixel_view
      class PixelWidget (line 24) | class PixelWidget
      type PixelItem (line 26) | struct PixelItem
      class PixelImage (line 32) | class PixelImage
      class PtCanvas (line 34) | class PtCanvas : public QWidget
        method PixelImage (line 65) | PixelImage* get_pimage(void) const { return pimage_.get(); }
        method setCompression (line 69) | void setCompression(int c) { compression_ = c; }

FILE: cp-profiler/src/cpprofiler/receiver_thread.cpp
  type cpprofiler (line 13) | namespace cpprofiler

FILE: cp-profiler/src/cpprofiler/receiver_thread.hh
  type cpprofiler (line 10) | namespace cpprofiler
    class Conductor (line 13) | class Conductor
    class Execution (line 14) | class Execution
    class ReceiverWorker (line 15) | class ReceiverWorker
    class Settings (line 16) | class Settings
    class ReceiverThread (line 18) | class ReceiverThread : public QThread

FILE: cp-profiler/src/cpprofiler/receiver_worker.cpp
  type cpprofiler (line 16) | namespace cpprofiler
    function ArrayToInt (line 24) | static int32_t ArrayToInt(const QByteArray &ba)

FILE: cp-profiler/src/cpprofiler/receiver_worker.hh
  class QTcpSocket (line 9) | class QTcpSocket
  type cpprofiler (line 11) | namespace cpprofiler
    class Conductor (line 14) | class Conductor
    class Execution (line 15) | class Execution
    class Settings (line 16) | class Settings
    class ReceiverWorker (line 18) | class ReceiverWorker : public QObject
      type ReadState (line 32) | struct ReadState

FILE: cp-profiler/src/cpprofiler/settings.hh
  type cpprofiler (line 3) | namespace cpprofiler
    class Settings (line 6) | class Settings

FILE: cp-profiler/src/cpprofiler/solver_data.cpp
  type cpprofiler (line 7) | namespace cpprofiler
    function parse_reasons_json (line 11) | static std::vector<int> parse_reasons_json(QJsonValue &json_arr)
    function parse_nogoods_json (line 30) | static std::vector<SolverID> parse_nogoods_json(QJsonValue &json_arr)

FILE: cp-profiler/src/cpprofiler/solver_data.hh
  type cpprofiler (line 10) | namespace cpprofiler
    class NameMap (line 13) | class NameMap
    class IdMap (line 15) | class IdMap
      method SolverID (line 29) | SolverID getUID(NodeID nid) const
    class SolverData (line 44) | class SolverData
      method NodeID (line 64) | NodeID getNodeId(SolverID sid) const
      method setNodeId (line 69) | void setNodeId(SolverID sid, NodeID nid)
      method SolverID (line 74) | SolverID getSolverID(NodeID nid) const
      method setNogood (line 101) | void setNogood(NodeID nid, const std::string &orig, const std::strin...
      method setNogood (line 106) | void setNogood(NodeID nid, const std::string &orig)
      method Nogood (line 111) | const Nogood &getNogood(NodeID nid) const
      method setInfo (line 124) | void setInfo(NodeID nid, const std::string &orig)
      method Info (line 129) | Info getInfo(NodeID nid) const
      method hasNogoods (line 146) | bool hasNogoods() const
      method hasInfo (line 152) | bool hasInfo() const

FILE: cp-profiler/src/cpprofiler/solver_id.hh
  type cpprofiler (line 1) | namespace cpprofiler
    type SolverID (line 5) | struct SolverID
      method toString (line 14) | std::string toString() const
  type std (line 28) | namespace std
    type hash<cpprofiler::SolverID> (line 31) | struct hash<cpprofiler::SolverID>

FILE: cp-profiler/src/cpprofiler/stats_bar.hpp
  type cpprofiler (line 8) | namespace cpprofiler
    class NodeStatsBar (line 11) | class NodeStatsBar : public QWidget
      method NodeStatsBar (line 29) | NodeStatsBar(QWidget *parent, const tree::NodeStats &ns) : QWidget(p...
      method update (line 64) | void update()

FILE: cp-profiler/src/cpprofiler/tcp_server.cpp
  type cpprofiler (line 3) | namespace cpprofiler

FILE: cp-profiler/src/cpprofiler/tcp_server.hh
  type cpprofiler (line 8) | namespace cpprofiler
    class TcpServer (line 11) | class TcpServer : public QTcpServer

FILE: cp-profiler/src/cpprofiler/tests/execution_test.cpp
  type cpprofiler (line 20) | namespace cpprofiler
    type tests (line 22) | namespace tests
      type execution (line 24) | namespace execution
        function copy_test (line 27) | void copy_test(utils::Array<int> arr)
        function array_test (line 32) | void array_test()
        function binary_tree_execution (line 40) | void binary_tree_execution(Conductor &conductor)
        function nary_execution (line 113) | void nary_execution(Conductor &conductor)
        function larger_nary_execution (line 139) | void larger_nary_execution(Conductor &conductor)
        function simple_nary_execution (line 178) | void simple_nary_execution(Conductor &conductor)
        function binary_test_1_for_identical_subtrees (line 192) | void binary_test_1_for_identical_subtrees(Conductor &conductor)
        function binary_test_2_for_identical_subtrees (line 219) | void binary_test_2_for_identical_subtrees(Conductor &conductor)
        function build_for_comparison_a (line 258) | void build_for_comparison_a(tree::NodeTree &tree)
        function build_for_comparison_b (line 276) | void build_for_comparison_b(tree::NodeTree &tree)
        function comparison (line 294) | void comparison(Conductor &c)
        function comparison2 (line 306) | void comparison2(Conductor &c)
        function tree_building (line 322) | void tree_building(Conductor &c)
        function hiding_failed_test (line 339) | void hiding_failed_test(Conductor &c)
        function restart_tree (line 364) | void restart_tree(Conductor &c)
        function load_execution (line 385) | static void load_execution(Conductor &c, const char *path)
        function save_and_load (line 400) | static void save_and_load(Conductor &c, const char *path)
        function db_create_tree (line 421) | static void db_create_tree(Conductor &c)
        function save_search (line 435) | static void save_search(Conductor &c)
        function ss_analysis (line 445) | static void ss_analysis(Conductor &c)
        function nogood_dialog (line 462) | static void nogood_dialog(Conductor &c)
        function run (line 496) | void run(Conductor &c)

FILE: cp-profiler/src/cpprofiler/tests/execution_test.hh
  type cpprofiler (line 4) | namespace cpprofiler
    class Conductor (line 6) | class Conductor
    type tests (line 11) | namespace tests
      type execution (line 13) | namespace execution
  type cpprofiler (line 9) | namespace cpprofiler
    class Conductor (line 6) | class Conductor
    type tests (line 11) | namespace tests
      type execution (line 13) | namespace execution

FILE: cp-profiler/src/cpprofiler/tests/tree_test.cpp
  type cpprofiler (line 9) | namespace cpprofiler
    type tests (line 11) | namespace tests
      type tree_test (line 13) | namespace tree_test
        class TestClass (line 16) | class TestClass
          method TestClass (line 23) | TestClass()
          method TestClass (line 35) | TestClass(const TestClass &other)
          method TestClass (line 42) | TestClass(TestClass &&other)
          method TestClass (line 48) | TestClass &operator=(const TestClass &other)
        function array_usage (line 58) | void array_usage()
        function growing_tree (line 72) | void growing_tree()
        function run (line 95) | void run()

FILE: cp-profiler/src/cpprofiler/tests/tree_test.hh
  type cpprofiler (line 4) | namespace cpprofiler
    type tests (line 7) | namespace tests
      type tree_test (line 10) | namespace tree_test

FILE: cp-profiler/src/cpprofiler/tree/cursors/drawing_cursor.cpp
  type cpprofiler (line 18) | namespace cpprofiler
    type tree (line 20) | namespace tree
      type colors (line 24) | namespace colors
      function drawTriangle (line 72) | static void drawTriangle(QPainter &painter, int x, int y, bool selec...
      function drawShape (line 104) | static void drawShape(QPainter &painter, int x, int y, NodeID nid, c...
      function drawBoundingBox (line 143) | static void drawBoundingBox(QPainter &painter, int x, int y, NodeID ...

FILE: cp-profiler/src/cpprofiler/tree/cursors/drawing_cursor.hh
  class QPainter (line 9) | class QPainter
  type cpprofiler (line 11) | namespace cpprofiler
    class UserData (line 13) | class UserData
    type tree (line 15) | namespace tree
      class VisualFlags (line 17) | class VisualFlags
      class Layout (line 26) | class Layout
      class DrawingCursor (line 29) | class DrawingCursor : public NodeCursor
    type tree (line 23) | namespace tree
      class VisualFlags (line 17) | class VisualFlags
      class Layout (line 26) | class Layout
      class DrawingCursor (line 29) | class DrawingCursor : public NodeCursor
  type cpprofiler (line 21) | namespace cpprofiler
    class UserData (line 13) | class UserData
    type tree (line 15) | namespace tree
      class VisualFlags (line 17) | class VisualFlags
      class Layout (line 26) | class Layout
      class DrawingCursor (line 29) | class DrawingCursor : public NodeCursor
    type tree (line 23) | namespace tree
      class VisualFlags (line 17) | class VisualFlags
      class Layout (line 26) | class Layout
      class DrawingCursor (line 29) | class DrawingCursor : public NodeCursor

FILE: cp-profiler/src/cpprofiler/tree/cursors/hide_failed_cursor.cpp
  type cpprofiler (line 6) | namespace cpprofiler
    type tree (line 8) | namespace tree
      function should_hide (line 27) | inline static bool should_hide(const NodeTree &nt, const VisualFlags...

FILE: cp-profiler/src/cpprofiler/tree/cursors/hide_failed_cursor.hh
  type cpprofiler (line 5) | namespace cpprofiler
    type tree (line 7) | namespace tree
      class VisualFlags (line 10) | class VisualFlags
      class LayoutComputer (line 11) | class LayoutComputer
      class HideFailedCursor (line 15) | class HideFailedCursor : public NodeCursor

FILE: cp-profiler/src/cpprofiler/tree/cursors/hide_not_highlighted_cursor.cpp
  type cpprofiler (line 6) | namespace cpprofiler
    type tree (line 9) | namespace tree

FILE: cp-profiler/src/cpprofiler/tree/cursors/hide_not_highlighted_cursor.hh
  type cpprofiler (line 6) | namespace cpprofiler
    type tree (line 9) | namespace tree
      class VisualFlags (line 12) | class VisualFlags
      class LayoutComputer (line 13) | class LayoutComputer
      class HideNotHighlightedCursor (line 16) | class HideNotHighlightedCursor : public NodeCursor

FILE: cp-profiler/src/cpprofiler/tree/cursors/layout_cursor.cpp
  type cpprofiler (line 24) | namespace cpprofiler
    type tree (line 26) | namespace tree
      function distance_between (line 51) | static int distance_between(const Shape &s1, const Shape &s2)
      function ShapeUniqPtr (line 68) | static ShapeUniqPtr combine_shapes(const Shape &s1, const Shape &s2,...
      function Shape (line 117) | static Shape merge_left(const Shape &s1, const Shape &s2, int &dist)
      function Extent (line 163) | static Extent calculateForSingleNode(NodeID nid, const NodeTree &nt,...
      function computeForNodeBinary (line 202) | inline static void computeForNodeBinary(NodeID nid, Layout &layout, ...
      function compute_distances (line 230) | inline static std::vector<int> compute_distances(NodeID nid, int nki...
      function kids_max_depth (line 246) | inline static int kids_max_depth(NodeID nid, int nkids, const Layout...
      function computeForNodeNary (line 258) | static inline void computeForNodeNary(NodeID nid, int nkids, Layout ...
      function ShapeUniqPtr (line 327) | static ShapeUniqPtr calc_for_sized_rect(int size)

FILE: cp-profiler/src/cpprofiler/tree/cursors/layout_cursor.hh
  type cpprofiler (line 8) | namespace cpprofiler
    type tree (line 10) | namespace tree
      class Layout (line 13) | class Layout
      class VisualFlags (line 14) | class VisualFlags
      class LayoutCursor (line 16) | class LayoutCursor : public NodeCursor

FILE: cp-profiler/src/cpprofiler/tree/cursors/node_cursor.cpp
  type cpprofiler (line 7) | namespace cpprofiler
    type tree (line 9) | namespace tree

FILE: cp-profiler/src/cpprofiler/tree/cursors/node_cursor.hh
  type cpprofiler (line 6) | namespace cpprofiler
    type tree (line 8) | namespace tree
      class Structure (line 11) | class Structure
      class NodeInfo (line 12) | class NodeInfo
      class NodeTree (line 13) | class NodeTree
      class NodeCursor (line 15) | class NodeCursor
        method NodeID (line 31) | inline NodeID cur_node() const { return node_; }
        method cur_alt (line 33) | inline int cur_alt() const { return cur_alt_; }
        method NodeID (line 35) | inline NodeID start_node() const { return start_node_; }

FILE: cp-profiler/src/cpprofiler/tree/cursors/nodevisitor.hh
  type cpprofiler (line 4) | namespace cpprofiler
    type tree (line 6) | namespace tree
      class NodeVisitor (line 10) | class NodeVisitor
      class PreorderNodeVisitor (line 21) | class PreorderNodeVisitor : public NodeVisitor<Cursor>
      class PostorderNodeVisitor (line 39) | class PostorderNodeVisitor : public NodeVisitor<Cursor>

FILE: cp-profiler/src/cpprofiler/tree/layout.cpp
  type cpprofiler (line 8) | namespace cpprofiler
    type tree (line 10) | namespace tree

FILE: cp-profiler/src/cpprofiler/tree/layout.hh
  type cpprofiler (line 13) | namespace cpprofiler
    type tree (line 15) | namespace tree
      class Shape (line 18) | class Shape
      class LayoutComputer (line 19) | class LayoutComputer
      class Structure (line 20) | class Structure
      class BoundingBox (line 21) | class BoundingBox
      class ShapeDeleter (line 22) | class ShapeDeleter
      class Layout (line 26) | class Layout : public QObject
        method setChildOffset (line 47) | void setChildOffset(NodeID nid, double offset) { child_offsets_[ni...
        method setLayoutDone (line 49) | void setLayoutDone(NodeID nid, bool val) { layout_done_[nid] = val; }
        method Shape (line 53) | const Shape *getShape(NodeID nid) const { return shapes_[nid].get(...
        method getOffset (line 57) | double getOffset(NodeID nid) const { return child_offsets_[nid]; }
        method isDirty (line 71) | bool isDirty(NodeID nid) const { return dirty_[nid]; }
        method setDirty (line 74) | void setDirty(NodeID nid, bool val) { dirty_[nid] = val; }
        method BoundingBox (line 77) | const BoundingBox &getBoundingBox(NodeID nid) const { return getSh...

FILE: cp-profiler/src/cpprofiler/tree/layout_computer.cpp
  type cpprofiler (line 17) | namespace cpprofiler
    type tree (line 19) | namespace tree

FILE: cp-profiler/src/cpprofiler/tree/layout_computer.hh
  class QMutex (line 4) | class QMutex
  type cpprofiler (line 11) | namespace cpprofiler
    type tree (line 13) | namespace tree
      class Layout (line 16) | class Layout
      class NodeTree (line 17) | class NodeTree
      class VisualFlags (line 18) | class VisualFlags
      class LayoutComputer (line 20) | class LayoutComputer
        method setDebugMode (line 51) | void setDebugMode(bool val) { debug_mode_ = val; }

FILE: cp-profiler/src/cpprofiler/tree/node.cpp
  type cpprofiler (line 8) | namespace cpprofiler
    type tree (line 10) | namespace tree
      function NodeID (line 26) | NodeID *Node::getPtr() const
      function NodeID (line 128) | NodeID Node::getChild(int alt) const
      function NodeID (line 193) | NodeID Node::getParent() const
      function QDebug (line 224) | QDebug &&operator<<(QDebug &&out, NodeStatus status)

FILE: cp-profiler/src/cpprofiler/tree/node.hh
  type cpprofiler (line 7) | namespace cpprofiler
    type tree (line 9) | namespace tree
      type no_child (line 12) | struct no_child : std::exception
      class Node (line 22) | class Node
        type Tag (line 25) | enum class Tag
        method Node (line 76) | Node &operator=(const Node &) = delete;
        method Node (line 77) | Node(const Node &) = delete;

FILE: cp-profiler/src/cpprofiler/tree/node_drawing.cpp
  type cpprofiler (line 6) | namespace cpprofiler
    type tree (line 8) | namespace tree
      type draw (line 10) | namespace draw
        type colors (line 13) | namespace colors
        function drawDiamond (line 40) | static void drawDiamond(QPainter &painter, int myx, int myy, bool ...
        function solution (line 59) | void solution(QPainter &painter, int x, int y, bool selected)
        function failure (line 74) | void failure(QPainter &painter, int x, int y, bool selected)
        function branch (line 89) | void branch(QPainter &painter, int x, int y, bool selected)
        function unexplored (line 105) | void unexplored(QPainter &painter, int x, int y, bool selected)
        function skipped (line 120) | void skipped(QPainter &painter, int x, int y, bool selected)
        function pentagon (line 135) | void pentagon(QPainter &painter, int x, int y, bool selected)
        function big_pentagon (line 156) | void big_pentagon(QPainter &painter, int x, int y, bool selected)
        function lantern (line 177) | void lantern(QPainter &painter, int x, int y, int size, bool selec...

FILE: cp-profiler/src/cpprofiler/tree/node_drawing.hh
  class QPainter (line 3) | class QPainter
  type cpprofiler (line 5) | namespace cpprofiler
    type tree (line 7) | namespace tree
      type draw (line 9) | namespace draw

FILE: cp-profiler/src/cpprofiler/tree/node_id.cpp
  type cpprofiler (line 3) | namespace cpprofiler
    type tree (line 5) | namespace tree

FILE: cp-profiler/src/cpprofiler/tree/node_id.hh
  type cpprofiler (line 9) | namespace cpprofiler
    type tree (line 11) | namespace tree
      class NodeID (line 14) | class NodeID
        method NodeID (line 26) | explicit NodeID(int nid = -1) : id(nid) {}
    type tree (line 51) | namespace tree
      class NodeID (line 14) | class NodeID
        method NodeID (line 26) | explicit NodeID(int nid = -1) : id(nid) {}
  type std (line 36) | namespace std
    type hash<cpprofiler::tree::NodeID> (line 39) | struct hash<cpprofiler::tree::NodeID>
  type cpprofiler (line 49) | namespace cpprofiler
    type tree (line 11) | namespace tree
      class NodeID (line 14) | class NodeID
        method NodeID (line 26) | explicit NodeID(int nid = -1) : id(nid) {}
    type tree (line 51) | namespace tree
      class NodeID (line 14) | class NodeID
        method NodeID (line 26) | explicit NodeID(int nid = -1) : id(nid) {}

FILE: cp-profiler/src/cpprofiler/tree/node_info.cpp
  type cpprofiler (line 5) | namespace cpprofiler
    type tree (line 7) | namespace tree
      function NodeStatus (line 44) | NodeStatus NodeInfo::getStatus(NodeID nid) const
    type tree (line 41) | namespace tree
      function NodeStatus (line 44) | NodeStatus NodeInfo::getStatus(NodeID nid) const
  type cpprofiler (line 39) | namespace cpprofiler
    type tree (line 7) | namespace tree
      function NodeStatus (line 44) | NodeStatus NodeInfo::getStatus(NodeID nid) const
    type tree (line 41) | namespace tree
      function NodeStatus (line 44) | NodeStatus NodeInfo::getStatus(NodeID nid) const

FILE: cp-profiler/src/cpprofiler/tree/node_info.hh
  type cpprofiler (line 11) | namespace cpprofiler
    type tree (line 13) | namespace tree
      type NodeStatus (line 16) | enum class NodeStatus
      type NodeFlag (line 18) | enum class NodeFlag
      type NumFlagLoc (line 23) | struct NumFlagLoc
      class NodeInfoEntry (line 29) | class NodeInfoEntry
      class NodeInfo (line 43) | class NodeInfo

FILE: cp-profiler/src/cpprofiler/tree/node_stats.hh
  type cpprofiler (line 4) | namespace cpprofiler
    type tree (line 6) | namespace tree
      class NodeStats (line 9) | class NodeStats : public QObject
        method branchCount (line 20) | int branchCount() const { return branch_; }
        method undeterminedCount (line 22) | int undeterminedCount() const { return undet_; }
        method failedCount (line 24) | int failedCount() const { return failed_; }
        method skippedCount (line 26) | int skippedCount() const { return skipped_; }
        method solvedCount (line 28) | int solvedCount() const { return solved_; }
        method maxDepth (line 30) | int maxDepth() const { return max_depth_; }
        method add_branch (line 32) | void add_branch(int n)
        method subtract_undetermined (line 37) | void subtract_undetermined(int n)
        method add_undetermined (line 42) | void add_undetermined(int n)
        method add_failed (line 47) | void add_failed(int n)
        method add_solved (line 52) | void add_solved(int n)
        method add_skipped (line 57) | void add_skipped(int n)
        method addNode (line 62) | void addNode(NodeStatus status)
        method inform_depth (line 96) | void inform_depth(int d)

FILE: cp-profiler/src/cpprofiler/tree/node_tree.cpp
  type cpprofiler (line 11) | namespace cpprofiler
    type tree (line 13) | namespace tree
      function NodeInfo (line 39) | const NodeInfo &NodeTree::node_info() const
      function NodeInfo (line 44) | NodeInfo &NodeTree::node_info()
      function NodeID (line 59) | NodeID NodeTree::createRoot(int kids, Label label)
      function is_closing (line 98) | static bool is_closing(NodeStatus status)
      function NodeID (line 142) | NodeID NodeTree::promoteNode(NodeID parent_id, int alt, int kids, tr...
      function NodeID (line 205) | NodeID NodeTree::getParent(NodeID nid) const
      function NodeID (line 210) | NodeID NodeTree::getRoot() const
      function NodeID (line 215) | NodeID NodeTree::getChild(NodeID nid, int alt) const
      function NodeStats (line 220) | const NodeStats &NodeTree::node_stats() const
      function SolverData (line 225) | const SolverData &NodeTree::solver_data() const
      function NodeStatus (line 235) | NodeStatus NodeTree::getStatus(NodeID nid) const
      function Label (line 274) | const Label NodeTree::getLabel(NodeID nid) const
      function Nogood (line 289) | const Nogood &NodeTree::getNogood(NodeID nid) const

FILE: cp-profiler/src/cpprofiler/tree/node_tree.hh
  type cpprofiler (line 14) | namespace cpprofiler
    class NameMap (line 16) | class NameMap
    class SolverData (line 17) | class SolverData
    type tree (line 22) | namespace tree
      class Structure (line 25) | class Structure
      class NodeInfo (line 26) | class NodeInfo
      class NodeTree (line 32) | class NodeTree : public QObject
        method setDone (line 80) | void setDone() { is_done_ = true; }
        method isDone (line 82) | bool isDone() const { return is_done_; }
  type cpprofiler (line 20) | namespace cpprofiler
    class NameMap (line 16) | class NameMap
    class SolverData (line 17) | class SolverData
    type tree (line 22) | namespace tree
      class Structure (line 25) | class Structure
      class NodeInfo (line 26) | class NodeInfo
      class NodeTree (line 32) | class NodeTree : public QObject
        method setDone (line 80) | void setDone() { is_done_ = true; }
        method isDone (line 82) | bool isDone() const { return is_done_; }

FILE: cp-profiler/src/cpprofiler/tree/node_widget.hh
  type cpprofiler (line 11) | namespace cpprofiler
    type tree (line 13) | namespace tree
      class NodeWidget (line 17) | class NodeWidget : public QWidget
        method paintEvent (line 25) | void paintEvent(QPaintEvent *) override
        method NodeWidget (line 82) | explicit NodeWidget(NodeStatus s) : m_status(s)

FILE: cp-profiler/src/cpprofiler/tree/shape.cpp
  type cpprofiler (line 6) | namespace cpprofiler
    type tree (line 8) | namespace tree

FILE: cp-profiler/src/cpprofiler/tree/shape.hh
  type cpprofiler (line 8) | namespace cpprofiler
    type tree (line 10) | namespace tree
      class Extent (line 14) | class Extent
        method Extent (line 22) | Extent(int l0, int r0) : l(l0), r(r0) {}
        method Extent (line 24) | Extent() = default;
      type BoundingBox (line 28) | struct BoundingBox
        method width (line 33) | int width() const
      class Shape (line 40) | class Shape
        method Shape (line 56) | Shape(std::initializer_list<Extent> init_list, const BoundingBox &bb)
        method height (line 60) | int height() const { return extents_.size(); }
        method Extent (line 63) | Extent &operator[](int depth) { return extents_[depth]; }
        method Extent (line 66) | const Extent &operator[](int depth) const { return extents_[depth]; }
        method setBoundingBox (line 69) | void setBoundingBox(BoundingBox bb) { bb_ = bb; }
        method BoundingBox (line 72) | const BoundingBox &boundingBox() const { return bb_; }
      class ShapeDeleter (line 80) | class ShapeDeleter

FILE: cp-profiler/src/cpprofiler/tree/structure.cpp
  type cpprofiler (line 11) | namespace cpprofiler
    type tree (line 13) | namespace tree
      function Mutex (line 21) | Mutex &Structure::getMutex() const
      function NodeID (line 26) | NodeID Structure::createRoot(int kids)
      function NodeID (line 44) | NodeID Structure::createNode(NodeID pid, int kids)
      function NodeID (line 56) | NodeID Structure::createChild(NodeID pid, int alt, int kids)
      function NodeID (line 63) | NodeID Structure::addExtraChild(NodeID pid)
      function NodeID (line 94) | NodeID Structure::getChild(NodeID pid, int alt) const
      function NodeID (line 99) | NodeID Structure::getParent(NodeID nid) const
      function NodeID (line 115) | NodeID Structure::getRoot() const

FILE: cp-profiler/src/cpprofiler/tree/structure.hh
  type cpprofiler (line 10) | namespace cpprofiler
    type tree (line 12) | namespace tree
      type invalid_tree (line 15) | struct invalid_tree : std::exception
      class LayoutComputer (line 23) | class LayoutComputer
      class Structure (line 29) | class Structure

FILE: cp-profiler/src/cpprofiler/tree/subtree_view.hh
  type cpprofiler (line 12) | namespace cpprofiler
    type tree (line 14) | namespace tree
      class SubtreeView (line 17) | class SubtreeView : public QWidget
        method SubtreeView (line 32) | SubtreeView(const NodeTree &nt)
        method QWidget (line 43) | QWidget *widget()
        method setNode (line 50) | void setNode(NodeID nid)

FILE: cp-profiler/src/cpprofiler/tree/traditional_view.cpp
  type cpprofiler (line 38) | namespace cpprofiler
    type tree (line 40) | namespace tree
      function NodeID (line 88) | NodeID TraditionalView::node() const
      function is_leaf (line 276) | static bool is_leaf(const NodeTree &nt, NodeID nid)
      function QWidget (line 517) | QWidget *TraditionalView::widget()
      function Layout (line 522) | const Layout &TraditionalView::layout() const
      function global_node_x_offset (line 533) | static int global_node_x_offset(const NodeTree &tree, const Layout &...
      function showSubtrees (line 638) | static void showSubtrees(const NodeTree &tree, VisualFlags &vf, Layo...
      class TreeHighlighter (line 646) | class TreeHighlighter : public QThread
        method TreeHighlighter (line 655) | TreeHighlighter(const NodeTree &tree, VisualFlags &vf, Layout &lo,...
        method run (line 658) | void run() override

FILE: cp-profiler/src/cpprofiler/tree/traditional_view.hh
  type cpprofiler (line 11) | namespace cpprofiler
    class UserData (line 13) | class UserData
    class SolverData (line 14) | class SolverData
    type tree (line 19) | namespace tree
      class Layout (line 22) | class Layout
      class LayoutComputer (line 23) | class LayoutComputer
      class NodeTree (line 24) | class NodeTree
      class NodeID (line 25) | class NodeID
      class Structure (line 26) | class Structure
      class TreeScrollArea (line 28) | class TreeScrollArea
      class TraditionalView (line 30) | class TraditionalView : public QObject
  type cpprofiler (line 17) | namespace cpprofiler
    class UserData (line 13) | class UserData
    class SolverData (line 14) | class SolverData
    type tree (line 19) | namespace tree
      class Layout (line 22) | class Layout
      class LayoutComputer (line 23) | class LayoutComputer
      class NodeTree (line 24) | class NodeTree
      class NodeID (line 25) | class NodeID
      class Structure (line 26) | class Structure
      class TreeScrollArea (line 28) | class TreeScrollArea
      class TraditionalView (line 30) | class TraditionalView : public QObject

FILE: cp-profiler/src/cpprofiler/tree/tree_scroll_area.cpp
  type cpprofiler (line 22) | namespace cpprofiler
    type tree (line 24) | namespace tree
      function drawGrid (line 29) | static void drawGrid(QPainter &painter, QSize size)
      function QPoint (line 142) | QPoint TreeScrollArea::getNodeCoordinate(NodeID nid)
      function getRealBB (line 156) | static std::pair<int, int> getRealBB(NodeID nid, const NodeTree &tre...
      function NodeID (line 182) | NodeID TreeScrollArea::findNodeClicked(int x, int y)

FILE: cp-profiler/src/cpprofiler/tree/tree_scroll_area.hh
  type cpprofiler (line 7) | namespace cpprofiler
    class UserData (line 9) | class UserData
    type tree (line 14) | namespace tree
      class NodeTree (line 17) | class NodeTree
      class Layout (line 18) | class Layout
      class VisualFlags (line 19) | class VisualFlags
      type DisplayState (line 21) | struct DisplayState
      class TreeScrollArea (line 29) | class TreeScrollArea : public QAbstractScrollArea
        method setDebugMode (line 67) | void setDebugMode(bool val) { debug_mode_ = val; }
  type cpprofiler (line 12) | namespace cpprofiler
    class UserData (line 9) | class UserData
    type tree (line 14) | namespace tree
      class NodeTree (line 17) | class NodeTree
      class Layout (line 18) | class Layout
      class VisualFlags (line 19) | class VisualFlags
      type DisplayState (line 21) | struct DisplayState
      class TreeScrollArea (line 29) | class TreeScrollArea : public QAbstractScrollArea
        method setDebugMode (line 67) | void setDebugMode(bool val) { debug_mode_ = val; }

FILE: cp-profiler/src/cpprofiler/tree/visual_flags.cpp
  type cpprofiler (line 3) | namespace cpprofiler
    type tree (line 5) | namespace tree

FILE: cp-profiler/src/cpprofiler/tree/visual_flags.hh
  type cpprofiler (line 7) | namespace cpprofiler
    type tree (line 9) | namespace tree
      class VisualFlags (line 12) | class VisualFlags

FILE: cp-profiler/src/cpprofiler/tree_builder.cpp
  type cpprofiler (line 14) | namespace cpprofiler

FILE: cp-profiler/src/cpprofiler/tree_builder.hh
  type cpprofiler (line 6) | namespace cpprofiler
    class Execution (line 9) | class Execution
    class TreeBuilder (line 11) | class TreeBuilder : public QObject

FILE: cp-profiler/src/cpprofiler/user_data.cpp
  type cpprofiler (line 3) | namespace cpprofiler

FILE: cp-profiler/src/cpprofiler/user_data.hh
  type cpprofiler (line 10) | namespace cpprofiler
    class UserData (line 14) | class UserData

FILE: cp-profiler/src/cpprofiler/utils/array.cpp
  type cpprofiler (line 3) | namespace cpprofiler
    type utils (line 5) | namespace utils

FILE: cp-profiler/src/cpprofiler/utils/array.hh
  type cpprofiler (line 8) | namespace cpprofiler
    type utils (line 10) | namespace utils
      class Array (line 14) | class Array
      function T (line 105) | T &Array<T>::operator[](int pos)
      function T (line 111) | const T &Array<T>::operator[](int pos) const

FILE: cp-profiler/src/cpprofiler/utils/debug.hh
  type cpprofiler (line 9) | namespace cpprofiler
    function to_string (line 18) | std::string to_string(const std::vector<T> &vec)
    function format (line 41) | inline std::string format(const char *temp)
    function format (line 47) | std::string format(const char *temp, T value, Types... args)
    function print (line 66) | void print(const char *temp, Types... args)

FILE: cp-profiler/src/cpprofiler/utils/debug_mutex.hh
  type cpprofiler (line 12) | namespace cpprofiler
    type utils (line 14) | namespace utils
      class DebugMutex (line 22) | class DebugMutex : public MyMutex
        method DebugMutex (line 26) | DebugMutex() {}
        method DebugMutex (line 28) | DebugMutex() : QMutex(QMutex::Recursive) {}
        method lock (line 31) | void lock(std::string msg)
        method tryLock (line 39) | bool tryLock()
        method unlock (line 46) | void unlock(std::string msg)
      class DebugMutexLocker (line 53) | class DebugMutexLocker
        method DebugMutexLocker (line 61) | DebugMutexLocker(DebugMutex *m, std::string msg = "") : m_mutex(m)...

FILE: cp-profiler/src/cpprofiler/utils/maybe_caller.cpp
  type cpprofiler (line 4) | namespace cpprofiler
    type utils (line 6) | namespace utils

FILE: cp-profiler/src/cpprofiler/utils/maybe_caller.hh
  type cpprofiler (line 7) | namespace cpprofiler
    type utils (line 9) | namespace utils
      class MaybeCaller (line 12) | class MaybeCaller : public QObject

FILE: cp-profiler/src/cpprofiler/utils/path_utils.cpp
  type cpprofiler (line 4) | namespace cpprofiler
    type utils (line 7) | namespace utils {
      function PathPair (line 12) | PathPair getPathPair(const string& path, bool omitDecomp) {

FILE: cp-profiler/src/cpprofiler/utils/path_utils.hh
  type cpprofiler (line 7) | namespace cpprofiler
    type utils (line 10) | namespace utils {
      type PathPair (line 15) | struct PathPair {

FILE: cp-profiler/src/cpprofiler/utils/perf_helper.hh
  type detail (line 11) | namespace detail
    type PerfInstance (line 15) | struct PerfInstance
    class PerformanceHelper (line 22) | class PerformanceHelper
      method begin (line 34) | void begin(const char *msg)
      method accumulate (line 40) | void accumulate(const char *msg)
      method end (line 45) | void end(const char *msg)
      method total (line 54) | void total(const char *msg)
      method end (line 61) | void end()
  type perf_helper (line 73) | namespace perf_helper
    type Timer (line 78) | struct Timer
      method begin (line 84) | void begin()
      method end (line 89) | int64_t end()

FILE: cp-profiler/src/cpprofiler/utils/std_ext.hh
  type cpprofiler (line 6) | namespace cpprofiler
    type utils (line 8) | namespace utils
      function make_unique_helper (line 12) | std::unique_ptr<T> make_unique_helper(std::false_type, Args &&... args)
      function make_unique_helper (line 18) | std::unique_ptr<T> make_unique_helper(std::true_type, Args &&... args)
      function make_unique (line 28) | std::unique_ptr<T> make_unique(Args &&... args)
      function make_unique (line 34) | std::unique_ptr<T> make_unique()

FILE: cp-profiler/src/cpprofiler/utils/string_utils.cpp
  type cpprofiler (line 9) | namespace cpprofiler
    type utils (line 11) | namespace utils
      function split (line 14) | vector<string> split(const string &str, char delim,
      function string (line 35) | string join(const vector<string>& strs, char sep) {

FILE: cp-profiler/src/cpprofiler/utils/string_utils.hh
  type cpprofiler (line 4) | namespace cpprofiler
    type utils (line 6) | namespace utils

FILE: cp-profiler/src/cpprofiler/utils/tree_utils.cpp
  type cpprofiler (line 8) | namespace cpprofiler
    type utils (line 10) | namespace utils
      function count_descendants (line 13) | int count_descendants(const NodeTree &nt, NodeID nid)
      function calculate_depth (line 31) | int calculate_depth(const NodeTree &nt, NodeID nid)
      function nodes_below (line 42) | std::vector<NodeID> nodes_below(const tree::NodeTree &nt, NodeID nid)
      function apply_below (line 72) | void apply_below(const NodeTree &nt, NodeID nid, const NodeAction &a...
      function pre_order_apply (line 88) | void pre_order_apply(const tree::NodeTree &nt, NodeID start, const N...
      function is_right_most_child (line 109) | bool is_right_most_child(const tree::NodeTree &nt, NodeID nid)
      function pre_order (line 122) | std::vector<NodeID> pre_order(const NodeTree &tree)
      function any_order (line 147) | std::vector<NodeID> any_order(const NodeTree &tree)
      function post_order (line 162) | std::vector<NodeID> post_order(const NodeTree &tree)
      function calc_subtree_sizes (line 192) | std::vector<int> calc_subtree_sizes(const tree::NodeTree &nt)

FILE: cp-profiler/src/cpprofiler/utils/tree_utils.hh
  type cpprofiler (line 8) | namespace cpprofiler
    type tree (line 10) | namespace tree
      class NodeTree (line 12) | class NodeTree
    type utils (line 18) | namespace utils
  type cpprofiler (line 16) | namespace cpprofiler
    type tree (line 10) | namespace tree
      class NodeTree (line 12) | class NodeTree
    type utils (line 18) | namespace utils

FILE: cp-profiler/src/cpprofiler/utils/utils.cpp
  type cpprofiler (line 6) | namespace cpprofiler
    type utils (line 8) | namespace utils
      function sleep_for_ms (line 11) | void sleep_for_ms(int ms)

FILE: cp-profiler/src/cpprofiler/utils/utils.hh
  type cpprofiler (line 8) | namespace cpprofiler
    type utils (line 10) | namespace utils
      function print (line 14) | void print(std::ostream &os, const std::unordered_map<K, T> &map)

FILE: cp-profiler/src/main_cpprofiler.cpp
  function main (line 13) | int main(int argc, char *argv[])

FILE: tests/testeditor.cpp
  type FindReplaceAction (line 209) | enum FindReplaceAction {

FILE: tests/testide.cpp
  function main (line 18) | int main(int argc, char *argv[])

FILE: tests/testide.h
  function class (line 7) | class TestIDE : public QObject
  function class (line 35) | class TestMocker {
Condensed preview — 267 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,311K chars).
[
  {
    "path": ".envrc",
    "chars": 9,
    "preview": "use flake"
  },
  {
    "path": ".gitignore",
    "chars": 18,
    "preview": "*.pro.user\nresult\n"
  },
  {
    "path": ".gitlab-ci.yml",
    "chars": 27331,
    "preview": "stages:\n  - build\n  - test\n  - package\n  - publish\n\ndefault:\n  interruptible: true\n\n.cache:\n  variables:\n    CCACHE_DIR:"
  },
  {
    "path": "LICENSE.txt",
    "chars": 16726,
    "preview": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\""
  },
  {
    "path": "MiniZincIDE/CHANGES",
    "chars": 22477,
    "preview": "2026-04-30\n  v2.9.7\n-  Update to MiniZinc 2.9.7.\n\n2026-04-24\n  v2.9.6\n-  Fix syntax highlighting of the `list` keyword ("
  },
  {
    "path": "MiniZincIDE/MiniZincIDE.pri",
    "chars": 2635,
    "preview": "QT       += core gui widgets websockets\n\nVERSION = 2.9.7\nDEFINES += MINIZINC_IDE_VERSION=\\\\\\\"$$VERSION\\\\\\\"\n\nbundled {\n  "
  },
  {
    "path": "MiniZincIDE/MiniZincIDE.pro",
    "chars": 162,
    "preview": "TARGET = MiniZincIDE\nTEMPLATE = app\n\nINCLUDEPATH += $$PWD/../\n\nSOURCES += main.cpp\n\ninclude($$PWD/MiniZincIDE.pri)\n\ntarg"
  },
  {
    "path": "MiniZincIDE/README.txt",
    "chars": 435,
    "preview": "================================================================\nMiniZinc IDE\n=========================================="
  },
  {
    "path": "MiniZincIDE/cheat_sheet.mzn",
    "chars": 4925,
    "preview": "                      %%%%%%%%%%%%%%%%%%%%%%%%\n                      %                      %\n                      % Mi"
  },
  {
    "path": "MiniZincIDE/checkupdatedialog.cpp",
    "chars": 288,
    "preview": "#include \"checkupdatedialog.h\"\n#include \"ui_checkupdatedialog.h\"\n\n#include <QPushButton>\n\nCheckUpdateDialog::CheckUpdate"
  },
  {
    "path": "MiniZincIDE/checkupdatedialog.h",
    "chars": 338,
    "preview": "#ifndef CHECKUPDATEDIALOG_H\n#define CHECKUPDATEDIALOG_H\n\n#include <QDialog>\n\nnamespace Ui {\nclass CheckUpdateDialog;\n}\n\n"
  },
  {
    "path": "MiniZincIDE/checkupdatedialog.ui",
    "chars": 7186,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>CheckUpdateDialog</class>\n <widget class=\"QDialog\" nam"
  },
  {
    "path": "MiniZincIDE/codechecker.cpp",
    "chars": 1980,
    "preview": "#include \"codechecker.h\"\n#include \"process.h\"\n\nCodeChecker::~CodeChecker()\n{\n    cancel();\n}\n\nvoid CodeChecker::connectS"
  },
  {
    "path": "MiniZincIDE/codechecker.h",
    "chars": 755,
    "preview": "#ifndef CHECKCODE_H\n#define CHECKCODE_H\n\n#include <QObject>\n\n#include \"codeeditor.h\"\n#include \"process.h\"\n\nclass CodeChe"
  },
  {
    "path": "MiniZincIDE/codeeditor.cpp",
    "chars": 31314,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/codeeditor.h",
    "chars": 4537,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/configwindow.cpp",
    "chars": 32218,
    "preview": "/*\n *  Main authors:\n *     Jason Nguyen <jason.nguyen@monash.edu>\n */\n\n/* This Source Code Form is subject to the terms"
  },
  {
    "path": "MiniZincIDE/configwindow.h",
    "chars": 6612,
    "preview": "/*\n *  Main authors:\n *     Jason Nguyen <jason.nguyen@monash.edu>\n */\n\n/* This Source Code Form is subject to the terms"
  },
  {
    "path": "MiniZincIDE/configwindow.ui",
    "chars": 29678,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>ConfigWindow</class>\n <widget class=\"QWidget\" name=\"Co"
  },
  {
    "path": "MiniZincIDE/dark_mode.css",
    "chars": 3275,
    "preview": "*,\nQTableView::item {\n    border-color: #444444;\n    color: #FFFFFF;\n}\n\nQMainWindow, QDialog, QToolBar, QAbstractScrollA"
  },
  {
    "path": "MiniZincIDE/darkmodenotifier.cpp",
    "chars": 4170,
    "preview": "#include \"darkmodenotifier.h\"\r\n\r\n#include <QApplication>\r\n#include <QSettings>\r\n\r\nDarkModeNotifier::DarkModeNotifier(QOb"
  },
  {
    "path": "MiniZincIDE/darkmodenotifier.h",
    "chars": 619,
    "preview": "#ifndef DARKMODENOTIFIER_H\r\n#define DARKMODENOTIFIER_H\r\n\r\n#include <QObject>\r\n\r\nclass DarkModeNotifier : public QObject\r"
  },
  {
    "path": "MiniZincIDE/darkmodenotifier_macos.mm",
    "chars": 2508,
    "preview": "#import <Cocoa/Cocoa.h>\r\n \r\n#include \"darkmodenotifier.h\"\r\n\r\n#include <functional>\r\n\r\n@interface DarkModeObserver : NSOb"
  },
  {
    "path": "MiniZincIDE/elapsedtimer.cpp",
    "chars": 661,
    "preview": "#include \"elapsedtimer.h\"\n\nElapsedTimer::ElapsedTimer(QObject* parent) : QObject(parent) {\n    connect(&_interval, &QTim"
  },
  {
    "path": "MiniZincIDE/elapsedtimer.h",
    "chars": 479,
    "preview": "#ifndef ELAPSEDTIMER_H\n#define ELAPSEDTIMER_H\n\n#include <QObject>\n\n#include <QTimer>\n#include <QElapsedTimer>\n\nclass Ela"
  },
  {
    "path": "MiniZincIDE/esclineedit.cpp",
    "chars": 265,
    "preview": "#include \"esclineedit.h\"\n\n#include <QKeyEvent>\n#include <QDebug>\n\nEscLineEdit::EscLineEdit(QWidget* parent) : QLineEdit("
  },
  {
    "path": "MiniZincIDE/esclineedit.h",
    "chars": 279,
    "preview": "#ifndef ESCLINEEDIT_H\n#define ESCLINEEDIT_H\n\n#include <QLineEdit>\n\nclass EscLineEdit : public QLineEdit\n{\n    Q_OBJECT\np"
  },
  {
    "path": "MiniZincIDE/exception.h",
    "chars": 2248,
    "preview": "#ifndef EXCEPTION_H\n#define EXCEPTION_H\n\n#include <QException>\n\nclass Exception : public QException\n{\npublic:\n    Except"
  },
  {
    "path": "MiniZincIDE/extraparamdialog.cpp",
    "chars": 4021,
    "preview": "#include \"extraparamdialog.h\"\n#include \"ui_extraparamdialog.h\"\n\n#include <QMouseEvent>\n\nExtraParamDialog::ExtraParamDial"
  },
  {
    "path": "MiniZincIDE/extraparamdialog.h",
    "chars": 1306,
    "preview": "#ifndef EXTRAPARAMDIALOG_H\n#define EXTRAPARAMDIALOG_H\n\n#include <QWidget>\n#include <QStandardItemModel>\n#include <QSortF"
  },
  {
    "path": "MiniZincIDE/extraparamdialog.ui",
    "chars": 2188,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>ExtraParamDialog</class>\n <widget class=\"QWidget\" name"
  },
  {
    "path": "MiniZincIDE/fzndoc.cpp",
    "chars": 383,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/fzndoc.h",
    "chars": 670,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/gotolinedialog.cpp",
    "chars": 655,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/gotolinedialog.h",
    "chars": 647,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/gotolinedialog.ui",
    "chars": 1825,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>GoToLineDialog</class>\n <widget class=\"QDialog\" name=\""
  },
  {
    "path": "MiniZincIDE/highlighter.cpp",
    "chars": 13568,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/highlighter.h",
    "chars": 2579,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/history.cpp",
    "chars": 6789,
    "preview": "#include \"history.h\"\r\n\r\n#include <QDateTime>\r\n#include <QJsonArray>\r\n#include <QJsonObject>\r\n#include <QJsonValue>\r\n#inc"
  },
  {
    "path": "MiniZincIDE/history.h",
    "chars": 2290,
    "preview": "#ifndef HISTORY_H\r\n#define HISTORY_H\r\n\r\n#include <QObject>\r\n#include <QString>\r\n#include <QStringList>\r\n#include <QMap>\r"
  },
  {
    "path": "MiniZincIDE/ide.cpp",
    "chars": 24318,
    "preview": "#include <QSettings>\n#include <QMessageBox>\n#include <QDesktopServices>\n#include <QJsonDocument>\n#include <QJsonObject>\n"
  },
  {
    "path": "MiniZincIDE/ide.h",
    "chars": 3039,
    "preview": "#ifndef IDE_H\n#define IDE_H\n\n#include <QApplication>\n#include <QFileSystemWatcher>\n#include <QNetworkAccessManager>\n#inc"
  },
  {
    "path": "MiniZincIDE/ideutils.cpp",
    "chars": 3466,
    "preview": "#include \"ideutils.h\"\r\n\r\n#include <QDir>\r\n#include <QFileInfo>\r\n#include <QCheckBox>\r\n#include <QLineEdit>\r\n#include <QS"
  },
  {
    "path": "MiniZincIDE/ideutils.h",
    "chars": 891,
    "preview": "#ifndef IDEUTILS_H\r\n#define IDEUTILS_H\r\n\r\n#include <QString>\r\n#include <QWidget>\r\n#include <QMimeData>\r\n#include <QTextE"
  },
  {
    "path": "MiniZincIDE/images/about.html",
    "chars": 871,
    "preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\"\n\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n<html><head>\n  <style typ"
  },
  {
    "path": "MiniZincIDE/main.cpp",
    "chars": 939,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/mainwindow.cpp",
    "chars": 113751,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/mainwindow.h",
    "chars": 10084,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/mainwindow.ui",
    "chars": 34344,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>MainWindow</class>\n <widget class=\"QMainWindow\" name=\""
  },
  {
    "path": "MiniZincIDE/minizincide.qrc",
    "chars": 1350,
    "preview": "<RCC>\n    <qresource prefix=\"/\">\n        <file>images/about.html</file>\n        <file>images/mznicon.png</file>\n        "
  },
  {
    "path": "MiniZincIDE/moocsubmission.cpp",
    "chars": 19403,
    "preview": "#include \"moocsubmission.h\"\n#include \"ui_moocsubmission.h\"\n#include \"ide.h\"\n#include \"mainwindow.h\"\n#include \"exception."
  },
  {
    "path": "MiniZincIDE/moocsubmission.h",
    "chars": 2428,
    "preview": "#ifndef MOOCSUBMISSION_H\n#define MOOCSUBMISSION_H\n\n#include <QDialog>\n#include <QTextStream>\n#include <QJsonObject>\n#inc"
  },
  {
    "path": "MiniZincIDE/moocsubmission.ui",
    "chars": 10183,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>MOOCSubmission</class>\n <widget class=\"QDialog\" name=\""
  },
  {
    "path": "MiniZincIDE/mznide-makefile.plist",
    "chars": 3686,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "MiniZincIDE/mznide-xcode.plist",
    "chars": 3706,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "MiniZincIDE/outputdockwidget.cpp",
    "chars": 208,
    "preview": "#include \"outputdockwidget.h\"\n#include <QCloseEvent>\n\nvoid OutputDockWidget::closeEvent(QCloseEvent *event) {\n    if (is"
  },
  {
    "path": "MiniZincIDE/outputdockwidget.h",
    "chars": 340,
    "preview": "#ifndef OUTPUTDOCKWIDGET_H\n#define OUTPUTDOCKWIDGET_H\n\n#include <QDockWidget>\n\nclass OutputDockWidget : public QDockWidg"
  },
  {
    "path": "MiniZincIDE/outputwidget.cpp",
    "chars": 38118,
    "preview": "#include \"outputwidget.h\"\r\n#include \"ui_outputwidget.h\"\r\n\r\n#include \"highlighter.h\"\r\n\r\n#include <cmath>\r\n\r\n#include <QTe"
  },
  {
    "path": "MiniZincIDE/outputwidget.h",
    "chars": 5889,
    "preview": "#ifndef OUTPUTWIDGET_H\r\n#define OUTPUTWIDGET_H\r\n\r\n#include <QWidget>\r\n#include <QTextCursor>\r\n#include <QTextObjectInter"
  },
  {
    "path": "MiniZincIDE/outputwidget.ui",
    "chars": 4006,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<ui version=\"4.0\">\r\n <class>OutputWidget</class>\r\n <widget class=\"QWidget\" name="
  },
  {
    "path": "MiniZincIDE/paramdialog.cpp",
    "chars": 4707,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/paramdialog.h",
    "chars": 1025,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/paramdialog.ui",
    "chars": 1740,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>ParamDialog</class>\n <widget class=\"QDialog\" name=\"Par"
  },
  {
    "path": "MiniZincIDE/preferencesdialog.cpp",
    "chars": 35249,
    "preview": "#include \"preferencesdialog.h\"\r\n#include \"ui_preferencesdialog.h\"\r\n\r\n#include \"exception.h\"\r\n#include \"ideutils.h\"\r\n#inc"
  },
  {
    "path": "MiniZincIDE/preferencesdialog.h",
    "chars": 2303,
    "preview": "#ifndef PREFERENCESDIALOG_H\r\n#define PREFERENCESDIALOG_H\r\n\r\n#include <QDialog>\r\n#include <QTemporaryFile>\r\n#include <QLi"
  },
  {
    "path": "MiniZincIDE/preferencesdialog.ui",
    "chars": 33178,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<ui version=\"4.0\">\r\n <class>PreferencesDialog</class>\r\n <widget class=\"QDialog\" "
  },
  {
    "path": "MiniZincIDE/process.cpp",
    "chars": 19790,
    "preview": "/*\n *  Main authors:\n *     Jason Nguyen <jason.nguyen@monash.edu>\n *     Guido Tack <guido.tack@monash.edu>\n */\n\n/* Thi"
  },
  {
    "path": "MiniZincIDE/process.h",
    "chars": 10339,
    "preview": "#ifndef PROCESS_H\n#define PROCESS_H\n\n#include <QProcess>\n#include <QTextStream>\n#include <QVersionNumber>\n#include <QTem"
  },
  {
    "path": "MiniZincIDE/profilecompilation.cpp",
    "chars": 1275,
    "preview": "#include \"profilecompilation.h\"\r\n#include <QFileInfo>\r\n\r\nPath::Path(const QString& path)\r\n{\r\n    auto items = path.split"
  },
  {
    "path": "MiniZincIDE/profilecompilation.h",
    "chars": 1350,
    "preview": "#ifndef PROFILE_COMPILATION_H\r\n#define PROFILE_COMPILATION_H\r\n\r\n#include <QString>\r\n#include <QStringList>\r\n#include <QV"
  },
  {
    "path": "MiniZincIDE/project.cpp",
    "chars": 16352,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/project.h",
    "chars": 7429,
    "preview": "/*\n *  Author:\n *     Guido Tack <guido.tack@monash.edu>\n *\n *  Copyright:\n *     NICTA 2013\n */\n\n/* This Source Code Fo"
  },
  {
    "path": "MiniZincIDE/projectbrowser.cpp",
    "chars": 3537,
    "preview": "#include \"projectbrowser.h\"\n#include \"ui_projectbrowser.h\"\n#include \"ide.h\"\n#include \"exception.h\"\n\n#include <QFileDialo"
  },
  {
    "path": "MiniZincIDE/projectbrowser.h",
    "chars": 1139,
    "preview": "#ifndef PROJECTBROWSER_H\n#define PROJECTBROWSER_H\n\n#include <QMenu>\n#include <QDir>\n#include <QWidget>\n#include <QStanda"
  },
  {
    "path": "MiniZincIDE/projectbrowser.ui",
    "chars": 1309,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>ProjectBrowser</class>\n <widget class=\"QWidget\" name=\""
  },
  {
    "path": "MiniZincIDE/server/connector.js",
    "chars": 3488,
    "preview": "const MiniZincIDE = (() => {\r\n    const callbacks = {};\r\n    const responses = [];\r\n    const freeSlots = [];\r\n    let u"
  },
  {
    "path": "MiniZincIDE/server/index.html",
    "chars": 10334,
    "preview": "<!DOCTYPE html>\r\n<html>\r\n\r\n<head>\r\n    <meta charset=\"utf-8\">\r\n    <title>%3 | MiniZincIDE</title>\r\n    <style>\r\n       "
  },
  {
    "path": "MiniZincIDE/server.cpp",
    "chars": 12934,
    "preview": "#include \"server.h\"\n\n#include <QWebSocket>\n#include <QJsonDocument>\n#include <QDesktopServices>\n\n#include \"ideutils.h\"\n#"
  },
  {
    "path": "MiniZincIDE/server.h",
    "chars": 2367,
    "preview": "#ifndef SERVER_H\n#define SERVER_H\n\n#include <QObject>\n#include <QTcpServer>\n#include <QtWebSockets/QtWebSockets>\n#includ"
  },
  {
    "path": "MiniZincIDE/solver.cpp",
    "chars": 25929,
    "preview": "#include \"solver.h\"\n#include \"process.h\"\n#include \"exception.h\"\n\n#include <QFileInfo>\n#include <QFile>\n#include <QJsonPa"
  },
  {
    "path": "MiniZincIDE/solver.h",
    "chars": 3619,
    "preview": "#ifndef SOLVER_H\n#define SOLVER_H\n\n#include <QJsonDocument>\n#include <QJsonObject>\n#include <QString>\n#include <QVariant"
  },
  {
    "path": "MiniZincIDE/theme.cpp",
    "chars": 3550,
    "preview": "#include \"theme.h\"\r\n\r\nQString Theme::styleSheet(bool darkMode) const\r\n{\r\n    auto style_sheet = QString(\"background-colo"
  },
  {
    "path": "MiniZincIDE/theme.h",
    "chars": 3552,
    "preview": "#ifndef THEME_H\r\n#define THEME_H\r\n\r\n#include <QObject>\r\n#include <QColor>\r\n#include <vector>\r\n\r\nstruct ThemeColor\r\n{\r\n  "
  },
  {
    "path": "MiniZincIDE.pro",
    "chars": 138,
    "preview": "TEMPLATE = subdirs\n\nSUBDIRS = \\\n    MiniZincIDE \\\n    tests\n\nlibminizinc {\n  SUBDIRS += libminizinc\n  MiniZincIDE.depend"
  },
  {
    "path": "README.md",
    "chars": 2235,
    "preview": "<p align=\"center\">\n  <a href=\"https://www.minizinc.org/\">\n    <img src=\"https://www.minizinc.org/MiniZn_logo.png\" alt=\"L"
  },
  {
    "path": "TODO.txt",
    "chars": 1426,
    "preview": "Features that would be nice to have:\n * Show types\n * Integrated global constraint library browser\n * Save all data file"
  },
  {
    "path": "cp-profiler/README.md",
    "chars": 12439,
    "preview": "# CP-Profiler\n\nCP-Profiler provides search tree visualisations for executions of constraint programming solvers.\n\n## Tab"
  },
  {
    "path": "cp-profiler/cp-profiler.pri",
    "chars": 6197,
    "preview": "SOURCES += \\\n    $$PWD/src/cpprofiler/core.cpp \\\n    $$PWD/src/cpprofiler/command_line_parser.cpp \\\n    $$PWD/src/cpprof"
  },
  {
    "path": "cp-profiler/cp-profiler.pro",
    "chars": 148,
    "preview": "TEMPLATE = app\n\nTARGET = cp-profiler\n\nQT += widgets network sql\n\nCONFIG += c++11\n\ninclude(cp-profiler.pri)\nSOURCES += $$"
  },
  {
    "path": "cp-profiler/src/cpp-integration/README.md",
    "chars": 1417,
    "preview": "\n#### 1. Create a connector instance\n\n```c++\nunsigned int port = 6565;\n```\n\n```c++\nConnector c(port);\n```\n\n#### 2. Estab"
  },
  {
    "path": "cp-profiler/src/cpp-integration/connector.hpp",
    "chars": 7135,
    "preview": "#ifndef CONNECTOR\n#define CONNECTOR\n\n#include \"message.hpp\"\n\n#include <iostream>\n#include <sstream>\n#include <vector>\n#i"
  },
  {
    "path": "cp-profiler/src/cpp-integration/message.hpp",
    "chars": 8160,
    "preview": "#ifndef MESSAGE_HH\n#define MESSAGE_HH\n\n#include <vector>\n#include <string>\n#include <cassert>\n#include <cstdint>\n\nnamesp"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/histogram_scene.cpp",
    "chars": 5445,
    "preview": "#include \"histogram_scene.hh\"\n#include \"pattern_rect.hh\"\n#include \"../utils/perf_helper.hh\"\n\nnamespace cpprofiler\n{\nname"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/histogram_scene.hh",
    "chars": 2147,
    "preview": "#ifndef CPPROFILER_ANALYSES_HISTOGRAM_SCENE\n#define CPPROFILER_ANALYSES_HISTOGRAM_SCENE\n\n#include <memory>\n#include <uno"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/merge_window.cpp",
    "chars": 16376,
    "preview": "#include \"merge_window.hh\"\n\n#include \"../tree/traditional_view.hh\"\n#include \"merging/pentagon_list_widget.hh\"\n#include \""
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/merge_window.hh",
    "chars": 1759,
    "preview": "#pragma once\n\n#include <QMainWindow>\n#include \"../tree/node_tree.hh\"\n#include \"merging/merge_result.hh\"\n\nnamespace cppro"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/merging/merge_result.hh",
    "chars": 353,
    "preview": "#pragma once\n\n#include \"../../core.hh\"\n#include <vector>\n\nnamespace cpprofiler\n{\nnamespace analysis\n{\n\nstruct PentagonIt"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/merging/pentagon_list_widget.hh",
    "chars": 3324,
    "preview": "#pragma once\n\n#include <QWidget>\n#include <QGraphicsView>\n#include <QVBoxLayout>\n\n#include \"merge_result.hh\"\n\n#include \""
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/merging/pentagon_rect.cpp",
    "chars": 1905,
    "preview": "#include \"pentagon_rect.hh\"\n\n#include \"merge_result.hh\"\n#include \"pentagon_list_widget.hh\"\n\n#include <QGraphicsRectItem>"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/merging/pentagon_rect.hh",
    "chars": 1024,
    "preview": "#pragma once\n\n#include <QGraphicsRectItem>\n#include \"../../core.hh\"\n\nnamespace cpprofiler\n{\nnamespace analysis\n{\n\nclass "
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/nogood_analysis_dialog.hh",
    "chars": 4641,
    "preview": "#pragma once\n\n#include <QDialog>\n#include <QStandardItemModel>\n#include <QSortFilterProxyModel>\n#include <QTableView>\n#i"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/path_comp.cpp",
    "chars": 1705,
    "preview": "#include \"path_comp.hh\"\n#include <algorithm>\n\nusing std::vector;\n\nnamespace cpprofiler\n{\nnamespace analysis\n{\n\n/// A wra"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/path_comp.hh",
    "chars": 342,
    "preview": "#include <vector>\n\n#include \"../core.hh\"\n\n#pragma once\n\nnamespace cpprofiler\n{\nnamespace analysis\n{\n\n/// Find unique lab"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/pattern_rect.cpp",
    "chars": 1082,
    "preview": "#include \"pattern_rect.hh\"\n#include \"histogram_scene.hh\"\n\nnamespace cpprofiler\n{\nnamespace analysis\n{\n\nstatic constexpr "
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/pattern_rect.hh",
    "chars": 615,
    "preview": "#pragma once\n\n#include \"../core.hh\"\n#include <QGraphicsRectItem>\n#include <memory>\n\nnamespace cpprofiler\n{\nnamespace ana"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/pentagon_counter.hpp",
    "chars": 686,
    "preview": "#include <QWidget>\n#include <QLabel>\n#include <QHBoxLayout>\n#include \"../tree/node_widget.hh\"\n\nnamespace cpprofiler\n{\nna"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/similar_subtree_analysis.cpp",
    "chars": 8076,
    "preview": "#include \"similar_subtree_analysis.hh\"\n#include \"../tree/node_tree.hh\"\n#include \"../tree/layout.hh\"\n#include \"../utils/t"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/similar_subtree_analysis.hh",
    "chars": 766,
    "preview": "#pragma once\n\n#include <vector>\n#include \"../core.hh\"\n#include \"subtree_pattern.hh\"\n\nnamespace cpprofiler\n{\n\nnamespace t"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/similar_subtree_window.cpp",
    "chars": 13555,
    "preview": "#include \"similar_subtree_window.hh\"\n\n#include <QGraphicsView>\n#include <QVBoxLayout>\n#include <QSplitter>\n#include <QGr"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/similar_subtree_window.hh",
    "chars": 2814,
    "preview": "\n#ifndef CPPROFILER_ANALYSIS_SIMILAR_SUBTREE_WINDOW_HH\n#define CPPROFILER_ANALYSIS_SIMILAR_SUBTREE_WINDOW_HH\n\n#include <"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/subtree_pattern.hh",
    "chars": 903,
    "preview": "#pragma once\n#include \"../core.hh\"\n\nnamespace cpprofiler\n{\nnamespace analysis\n{\n\n/// Pattern properties\nenum class Patte"
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/tree_merger.cpp",
    "chars": 8107,
    "preview": "#include \"tree_merger.hh\"\n#include \"../execution.hh\"\n#include \"../tree/structure.hh\"\n#include \"../core.hh\"\n\n#include \".."
  },
  {
    "path": "cp-profiler/src/cpprofiler/analysis/tree_merger.hh",
    "chars": 920,
    "preview": "#pragma once\n\n#include <QThread>\n#include <memory>\n\n#include \"merging/merge_result.hh\"\n\nnamespace cpprofiler\n{\n\nnamespac"
  },
  {
    "path": "cp-profiler/src/cpprofiler/command_line_parser.cpp",
    "chars": 1601,
    "preview": "\n#include \"command_line_parser.hh\"\n\nnamespace cpprofiler\n{\n\nnamespace cl_options\n{\nQCommandLineOption paths{\"paths\", \"Us"
  },
  {
    "path": "cp-profiler/src/cpprofiler/command_line_parser.hh",
    "chars": 650,
    "preview": "#pragma once\n\n#include <QCommandLineParser>\n#include <QString>\n\nnamespace cpprofiler\n{\n\nnamespace cl_options\n{\nextern QC"
  },
  {
    "path": "cp-profiler/src/cpprofiler/conductor.cpp",
    "chars": 17590,
    "preview": "#include \"conductor.hh\"\n#include \"tcp_server.hh\"\n#include \"receiver_thread.hh\"\n#include <iostream>\n#include <thread>\n#in"
  },
  {
    "path": "cp-profiler/src/cpprofiler/conductor.hh",
    "chars": 3046,
    "preview": "#ifndef CPPROFILER_CONDUCTOR_HH\n#define CPPROFILER_CONDUCTOR_HH\n\n#include <QMainWindow>\n#include <QStandardItemModel>\n#i"
  },
  {
    "path": "cp-profiler/src/cpprofiler/config.hh",
    "chars": 2074,
    "preview": "#pragma once\n\n#include <algorithm>\n\nnamespace cpprofiler\n{\nnamespace tree\n{\n\nnamespace layout\n{\nconstexpr int dist_y = 3"
  },
  {
    "path": "cp-profiler/src/cpprofiler/core.cpp",
    "chars": 822,
    "preview": "#include \"core.hh\"\n\nnamespace cpprofiler\n{\nnamespace tree\n{\n\nstd::ostream &operator<<(std::ostream &os, const NodeStatus"
  },
  {
    "path": "cp-profiler/src/cpprofiler/core.hh",
    "chars": 1476,
    "preview": "#ifndef CPPROFILER_GLOBAL_HH\n#define CPPROFILER_GLOBAL_HH\n\n#include <ostream>\n#include \"tree/node_id.hh\"\n#include \"utils"
  },
  {
    "path": "cp-profiler/src/cpprofiler/db_handler.cpp",
    "chars": 10094,
    "preview": "#include \"db_handler.hh\"\n\n#include <fstream>\n#include \"utils/debug.hh\"\n#include <QSqlDatabase>\n#include <QSqlQuery>\n#inc"
  },
  {
    "path": "cp-profiler/src/cpprofiler/db_handler.hh",
    "chars": 399,
    "preview": "#pragma once\n\n#include \"core.hh\"\n\nnamespace cpprofiler\n{\n\nclass Execution;\n\nnamespace db_handler\n{\n\n/// Save existing ex"
  },
  {
    "path": "cp-profiler/src/cpprofiler/execution.cpp",
    "chars": 874,
    "preview": "\n#include \"execution.hh\"\n#include \"name_map.hh\"\n#include \"tree/node_tree.hh\"\n#include \"user_data.hh\"\n#include \"utils/deb"
  },
  {
    "path": "cp-profiler/src/cpprofiler/execution.hh",
    "chars": 1415,
    "preview": "#ifndef CPPROFILER_EXECUTION_HH\n#define CPPROFILER_EXECUTION_HH\n\n#include \"solver_data.hh\"\n#include \"tree/node.hh\"\n#incl"
  },
  {
    "path": "cp-profiler/src/cpprofiler/execution_list.cpp",
    "chars": 1168,
    "preview": "#include \"execution_list.hh\"\n#include \"execution.hh\"\n\n#include <QDebug>\n#include <iostream>\n\nnamespace cpprofiler\n{\n\nExe"
  },
  {
    "path": "cp-profiler/src/cpprofiler/execution_list.hh",
    "chars": 652,
    "preview": "#ifndef CPPROFILER_EXECUTION_LIST\n#define CPPROFILER_EXECUTION_LIST\n\n#include <QStandardItemModel>\n#include <QTreeView>\n"
  },
  {
    "path": "cp-profiler/src/cpprofiler/execution_window.cpp",
    "chars": 19869,
    "preview": "#include \"execution_window.hh\"\n\n#include \"tree/traditional_view.hh\"\n#include \"pixel_views/pt_canvas.hh\"\n#include \"pixel_"
  },
  {
    "path": "cp-profiler/src/cpprofiler/execution_window.hh",
    "chars": 2206,
    "preview": "#ifndef CPPROFILER_EXECUTION_WINDOW\n#define CPPROFILER_EXECUTION_WINDOW\n\n#include <memory>\n#include <QMainWindow>\n#inclu"
  },
  {
    "path": "cp-profiler/src/cpprofiler/message_wrapper.hh",
    "chars": 844,
    "preview": "#ifndef CPPROFILER_MESSAGE_WRAPPER_HH\r\n#define CPPROFILER_MESSAGE_WRAPPER_HH\r\n\r\n#include <QMetaType>\r\n#include <memory>\r"
  },
  {
    "path": "cp-profiler/src/cpprofiler/name_map.cpp",
    "chars": 7471,
    "preview": "#include \"name_map.hh\"\n#include \"utils/debug.hh\"\n#include \"utils/string_utils.hh\"\n#include \"utils/path_utils.hh\"\n\n#inclu"
  },
  {
    "path": "cp-profiler/src/cpprofiler/name_map.hh",
    "chars": 1717,
    "preview": "#pragma once\n\n#include <string>\n#include <QString>\n#include <vector>\n#include <unordered_map>\n\n//// Name Map should get "
  },
  {
    "path": "cp-profiler/src/cpprofiler/nogood_dialog.cpp",
    "chars": 1634,
    "preview": "#include \"nogood_dialog.hh\"\n#include \"tree/node_tree.hh\"\n#include \"solver_data.hh\"\n\n#include <QTableView>\n#include <QVBo"
  },
  {
    "path": "cp-profiler/src/cpprofiler/nogood_dialog.hh",
    "chars": 412,
    "preview": "#pragma once\n\n#include <QDialog>\n#include <QStandardItemModel>\n#include \"core.hh\"\n\nnamespace cpprofiler\n{\n\nnamespace tre"
  },
  {
    "path": "cp-profiler/src/cpprofiler/options.hh",
    "chars": 268,
    "preview": "#pragma once\n\nnamespace cpprofiler\n{\n\nstruct Options\n{\n    std::string paths;\n    std::string mzn;\n    std::string save_"
  },
  {
    "path": "cp-profiler/src/cpprofiler/pixel_views/icicle_canvas.cpp",
    "chars": 10647,
    "preview": "#include \"icicle_canvas.hh\"\n#include \"pixel_image.hh\"\n#include \"pixel_widget.hh\"\n\n#include \"../utils/tree_utils.hh\"\n#inc"
  },
  {
    "path": "cp-profiler/src/cpprofiler/pixel_views/icicle_canvas.hh",
    "chars": 1140,
    "preview": "#pragma once\n\n#include <QWidget>\n#include <memory>\n\n#include \"../core.hh\"\n\nnamespace cpprofiler\n{\n\nnamespace utils\n{\ncla"
  },
  {
    "path": "cp-profiler/src/cpprofiler/pixel_views/pixel_image.cpp",
    "chars": 3124,
    "preview": "#include \"pixel_image.hh\"\n\n#include \"../utils/debug.hh\"\n\n#include <QImage>\n#include <cassert>\n\nnamespace cpprofiler\n{\n\nn"
  },
  {
    "path": "cp-profiler/src/cpprofiler/pixel_views/pixel_image.hh",
    "chars": 1274,
    "preview": "#pragma once\n\n#include <QObject>\n\n#include <cstdint>\n#include <vector>\n#include <memory>\n#include <QRgb>\n\nclass QImage;\n"
  },
  {
    "path": "cp-profiler/src/cpprofiler/pixel_views/pixel_item.hh",
    "chars": 114,
    "preview": "\n#pragma once\n\nnamespace cpprofiler\n{\n\nnamespace pixel_view\n{\n\n} // namespace pixel_view\n} // namespace cpprofiler"
  },
  {
    "path": "cp-profiler/src/cpprofiler/pixel_views/pixel_widget.cpp",
    "chars": 884,
    "preview": "#include \"pixel_widget.hh\"\n\n#include <QScrollBar>\n\nnamespace cpprofiler\n{\n\nnamespace pixel_view\n{\n\nvoid PixelWidget::mou"
  },
  {
    "path": "cp-profiler/src/cpprofiler/pixel_views/pixel_widget.hh",
    "chars": 1445,
    "preview": "#pragma once\n\n#include <QAbstractScrollArea>\n#include <QPainter>\n#include <QResizeEvent>\n\n#include <cmath> // std::ceil\n"
  },
  {
    "path": "cp-profiler/src/cpprofiler/pixel_views/pt_canvas.cpp",
    "chars": 7584,
    "preview": "#include \"pt_canvas.hh\"\n#include \"pixel_image.hh\"\n#include \"pixel_widget.hh\"\n#include \"../tree/node_tree.hh\"\n\n#include \""
  },
  {
    "path": "cp-profiler/src/cpprofiler/pixel_views/pt_canvas.hh",
    "chars": 1510,
    "preview": "#pragma once\n\n#include <QScrollArea>\n#include <QLabel>\n#include <QWidget>\n\n#include <memory>\n#include <set>\n\n#include \"."
  },
  {
    "path": "cp-profiler/src/cpprofiler/receiver_thread.cpp",
    "chars": 1567,
    "preview": "#include \"receiver_thread.hh\"\n\n#include \"receiver_worker.hh\"\n#include \"execution.hh\"\n#include \"../cpp-integration/messag"
  },
  {
    "path": "cp-profiler/src/cpprofiler/receiver_thread.hh",
    "chars": 746,
    "preview": "#ifndef CPPROFILER_RECEIVER_HH\n#define CPPROFILER_RECEIVER_HH\n\n#include <cstdint>\n#include <memory>\n#include <QThread>\n\n"
  },
  {
    "path": "cp-profiler/src/cpprofiler/receiver_worker.cpp",
    "chars": 4558,
    "preview": "#include \"receiver_worker.hh\"\n#include \"conductor.hh\"\n#include <iostream>\n#include <string>\n#include <thread>\n#include <"
  },
  {
    "path": "cp-profiler/src/cpprofiler/receiver_worker.hh",
    "chars": 1466,
    "preview": "#ifndef CPPROFILER_RECEIVER_WORKER_HH\n#define CPPROFILER_RECEIVER_WORKER_HH\n\n#include <QObject>\n#include <memory>\n\n#incl"
  },
  {
    "path": "cp-profiler/src/cpprofiler/settings.hh",
    "chars": 204,
    "preview": "#pragma once\n\nnamespace cpprofiler\n{\n\nclass Settings\n{\npublic:\n    /// delay in ms after receiving a new message\n    int"
  },
  {
    "path": "cp-profiler/src/cpprofiler/solver_data.cpp",
    "chars": 3233,
    "preview": "#include \"solver_data.hh\"\n\n#include <QJsonDocument>\n#include <QJsonObject>\n#include <QJsonArray>\n\nnamespace cpprofiler\n{"
  },
  {
    "path": "cp-profiler/src/cpprofiler/solver_data.hh",
    "chars": 3451,
    "preview": "#pragma once\n\n#include <QReadWriteLock>\n#include <unordered_map>\n\n#include \"core.hh\"\n\n#include \"solver_id.hh\"\n\nnamespace"
  },
  {
    "path": "cp-profiler/src/cpprofiler/solver_id.hh",
    "chars": 873,
    "preview": "namespace cpprofiler\n{\n\n/// Mimics UID\nstruct SolverID\n{\n    // Node number\n    int32_t nid;\n    // Restart id\n    int32"
  },
  {
    "path": "cp-profiler/src/cpprofiler/stats_bar.hpp",
    "chars": 2096,
    "preview": "#include <QWidget>\n#include <QLabel>\n#include <thread>\n\n#include \"tree/node_tree.hh\"\n#include \"tree/node_widget.hh\"\n\nnam"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tcp_server.cpp",
    "chars": 261,
    "preview": "#include \"tcp_server.hh\"\n\nnamespace cpprofiler\n{\n\nTcpServer::TcpServer(std::function<void(intptr_t)> callback)\n    : QTc"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tcp_server.hh",
    "chars": 425,
    "preview": "#ifndef CPPROFILER_TCP_SERVER_HH\n#define CPPROFILER_TCP_SERVER_HH\n\n#include <QTcpServer>\n#include <functional>\n#include "
  },
  {
    "path": "cp-profiler/src/cpprofiler/tests/execution_test.cpp",
    "chars": 17208,
    "preview": "#include \"execution_test.hh\"\n\n#include \"../core.hh\"\n#include \"../conductor.hh\"\n#include \"../user_data.hh\"\n\n#include \"../"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tests/execution_test.hh",
    "chars": 274,
    "preview": "#ifndef CPPROFILER_TESTS_EXECUTION_TEST_HH\n#define CPPROFILER_TESTS_EXECUTION_TEST_HH\n\nnamespace cpprofiler\n{\nclass Cond"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tests/tree_test.cpp",
    "chars": 1703,
    "preview": "#include \"../tree/node_tree.hh\"\n#include \"../tree/structure.hh\"\n\n#include \"../utils/array.hh\"\n#include \"../utils/debug.h"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tests/tree_test.hh",
    "chars": 212,
    "preview": "#ifndef CPPROFILER_TESTS_TREE_TEST_HH\n#define CPPROFILER_TESTS_TREE_TEST_HH\n\nnamespace cpprofiler\n{\n\nnamespace tests\n{\n\n"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/cursors/drawing_cursor.cpp",
    "chars": 9523,
    "preview": "#include \"drawing_cursor.hh\"\n#include \"../../config.hh\"\n#include \"../layout.hh\"\n#include \"../node_info.hh\"\n#include \"../"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/cursors/drawing_cursor.hh",
    "chars": 1358,
    "preview": "#ifndef CPPROFILER_TREE_CURSORS_DRAWING_CURSOR_HH\n#define CPPROFILER_TREE_CURSORS_DRAWING_CURSOR_HH\n\n#include \"node_curs"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/cursors/hide_failed_cursor.cpp",
    "chars": 1325,
    "preview": "#include \"hide_failed_cursor.hh\"\n#include \"../node_tree.hh\"\n#include \"../visual_flags.hh\"\n#include \"../layout_computer.h"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/cursors/hide_failed_cursor.hh",
    "chars": 1137,
    "preview": "#pragma once\n\n#include \"node_cursor.hh\"\n\nnamespace cpprofiler\n{\nnamespace tree\n{\n\nclass VisualFlags;\nclass LayoutCompute"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/cursors/hide_not_highlighted_cursor.cpp",
    "chars": 1380,
    "preview": "#include \"hide_not_highlighted_cursor.hh\"\n#include \"../visual_flags.hh\"\n#include \"../layout_computer.hh\"\n#include \"../no"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/cursors/hide_not_highlighted_cursor.hh",
    "chars": 745,
    "preview": "#pragma once\n\n#include \"node_cursor.hh\"\n#include <QHash>\n\nnamespace cpprofiler\n{\n\nnamespace tree\n{\n\nclass VisualFlags;\nc"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/cursors/layout_cursor.cpp",
    "chars": 14060,
    "preview": "\n#include \"layout_cursor.hh\"\n#include \"../../config.hh\"\n#include \"../node_id.hh\"\n#include <iostream>\n#include <QDebug>\n#"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/cursors/layout_cursor.hh",
    "chars": 789,
    "preview": "#ifndef CPPROFILER_TREE_CURSORS_LAYOUT_CURSOR\n#define CPPROFILER_TREE_CURSORS_LAYOUT_CURSOR\n\n#include <vector>\n#include "
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/cursors/node_cursor.cpp",
    "chars": 1118,
    "preview": "#include \"node_cursor.hh\"\n\n#include \"../structure.hh\"\n#include \"../node_tree.hh\"\n#include <QDebug>\n\nnamespace cpprofiler"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/cursors/node_cursor.hh",
    "chars": 1473,
    "preview": "#ifndef CPPROFILER_TREE_CURSOR_NODE_CURSOR_HH\n#define CPPROFILER_TREE_CURSOR_NODE_CURSOR_HH\n\n#include \"../node_id.hh\"\n\nn"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/cursors/nodevisitor.hh",
    "chars": 1139,
    "preview": "#ifndef CPPROFILER_TREE_CURSORS_NODE_VISITOR_HH\n#define CPPROFILER_TREE_CURSORS_NODE_VISITOR_HH\n\nnamespace cpprofiler\n{\n"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/cursors/nodevisitor.hpp",
    "chars": 1832,
    "preview": "template <typename Cursor>\nNodeVisitor<Cursor>::NodeVisitor(const Cursor &c) : m_cursor(c) {}\n\ntemplate <typename Cursor"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/layout.cpp",
    "chars": 1006,
    "preview": "#include \"layout.hh\"\n\n#include <QDebug>\n#include <iostream>\n\n#include \"../utils/std_ext.hh\"\n\nnamespace cpprofiler\n{\nname"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/layout.hh",
    "chars": 2266,
    "preview": "#ifndef CPPROFILER_TREE_LAYOUT_HH\n#define CPPROFILER_TREE_LAYOUT_HH\n\n#include <vector>\n#include <memory>\n#include <unord"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/layout_computer.cpp",
    "chars": 2156,
    "preview": "#include \"layout_computer.hh\"\n#include \"layout.hh\"\n#include \"structure.hh\"\n#include \"node_tree.hh\"\n#include \"shape.hh\"\n#"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/layout_computer.hh",
    "chars": 1065,
    "preview": "#ifndef CPPROFILER_TREE_LAYOUT_COMPUTER_HH\n#define CPPROFILER_TREE_LAYOUT_COMPUTER_HH\n\nclass QMutex;\n\n#include \"node_id."
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/node.cpp",
    "chars": 4693,
    "preview": "#include \"node.hh\"\n\n#include <cassert>\n#include <iostream>\n#include <exception>\n#include <QDebug>\n\nnamespace cpprofiler\n"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/node.hh",
    "chars": 1749,
    "preview": "#ifndef CPPROFILER_TREE_NODE\n#define CPPROFILER_TREE_NODE\n\n#include <vector>\n#include \"../core.hh\"\n\nnamespace cpprofiler"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/node_drawing.cpp",
    "chars": 5466,
    "preview": "#include \"node_drawing.hh\"\n#include \"../config.hh\"\n\n#include <QPainter>\n\nnamespace cpprofiler\n{\nnamespace tree\n{\nnamespa"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/node_drawing.hh",
    "chars": 715,
    "preview": "#pragma once\n\nclass QPainter;\n\nnamespace cpprofiler\n{\nnamespace tree\n{\nnamespace draw\n{\n\nvoid solution(QPainter &painter"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/node_id.cpp",
    "chars": 266,
    "preview": "#include \"node_id.hh\"\n\nnamespace cpprofiler\n{\nnamespace tree\n{\n\nbool operator==(const NodeID &lhs, const NodeID &rhs)\n{\n"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/node_id.hh",
    "chars": 1093,
    "preview": "#ifndef CPPROFILER_TREE_NODE_ID_HH\n#define CPPROFILER_TREE_NODE_ID_HH\n\n#include <cstdint>\n#include <functional>\n\n#includ"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/node_info.cpp",
    "chars": 2011,
    "preview": "#include \"node_info.hh\"\n#include \"node.hh\"\n#include <QDebug>\n\nnamespace cpprofiler\n{\nnamespace tree\n{\n\nconstexpr NumFlag"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/node_info.hh",
    "chars": 1145,
    "preview": "#ifndef CPPROFILER_TREE_NODE_INFO\n#define CPPROFILER_TREE_NODE_INFO\n\n#include \"../core.hh\"\n\n#include <bitset>\n#include <"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/node_stats.hh",
    "chars": 1834,
    "preview": "#include <QObject>\n#include \"../core.hh\"\n\nnamespace cpprofiler\n{\nnamespace tree\n{\n\nclass NodeStats : public QObject\n{\n  "
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/node_tree.cpp",
    "chars": 7580,
    "preview": "#include \"node_tree.hh\"\n\n#include \"structure.hh\"\n#include \"node_info.hh\"\n#include \"../solver_data.hh\"\n#include \"../utils"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/node_tree.hh",
    "chars": 5078,
    "preview": "#ifndef CPPROFILER_TREE_NODE_TREE_HH\n#define CPPROFILER_TREE_NODE_TREE_HH\n\n#include <QObject>\n#include <memory>\n#include"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/node_widget.hh",
    "chars": 2752,
    "preview": "#pragma once\n\n#include <QWidget>\n#include <QDebug>\n#include <QPainter>\n#include \"../config.hh\"\n#include \"../core.hh\"\n\n#i"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/shape.cpp",
    "chars": 805,
    "preview": "#include \"shape.hh\"\n#include \"../config.hh\"\n#include <QDebug>\n#include <ostream>\n\nnamespace cpprofiler\n{\nnamespace tree\n"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/shape.hh",
    "chars": 2048,
    "preview": "#ifndef CPPROFILER_TREE_SHAPE\n#define CPPROFILER_TREE_SHAPE\n\n#include \"../utils/array.hh\"\n#include <ostream>\n#include <i"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/structure.cpp",
    "chars": 3033,
    "preview": "#include \"structure.hh\"\n\n#include <iostream>\n#include <exception>\n#include <stack>\n#include <algorithm>\n#include <QDebug"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/structure.hh",
    "chars": 2654,
    "preview": "#ifndef CPPROFILER_NODE_TREE_HH\n#define CPPROFILER_NODE_TREE_HH\n\n#include \"node.hh\"\n\n#include \"../core.hh\"\n\n#include \"me"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/subtree_view.hh",
    "chars": 1307,
    "preview": "#pragma once\n\n#include <QWidget>\n\n#include \"../user_data.hh\"\n#include \"tree_scroll_area.hh\"\n#include \"layout_computer.hh"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/traditional_view.cpp",
    "chars": 18890,
    "preview": "#include \"traditional_view.hh\"\n#include \"tree_scroll_area.hh\"\n#include \"layout.hh\"\n#include \"structure.hh\"\n#include \"nod"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/traditional_view.hh",
    "chars": 6054,
    "preview": "#ifndef CPPROFILER_TREE_TRADITIONAL_VIEW_HH\n#define CPPROFILER_TREE_TRADITIONAL_VIEW_HH\n\n#include <QWidget>\n\n#include <m"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/tree_scroll_area.cpp",
    "chars": 7991,
    "preview": "#include \"tree_scroll_area.hh\"\n\n#include <QPainter>\n#include <QScrollBar>\n#include <QMouseEvent>\n\n#include <cmath>\n#incl"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/tree_scroll_area.hh",
    "chars": 1450,
    "preview": "#pragma once\n\n#include <QAbstractScrollArea>\n\n#include \"../core.hh\"\n\nnamespace cpprofiler\n{\nclass UserData;\n}\n\nnamespace"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/visual_flags.cpp",
    "chars": 2197,
    "preview": "#include \"visual_flags.hh\"\n\nnamespace cpprofiler\n{\nnamespace tree\n{\n\nvoid VisualFlags::ensure_id_exists(NodeID nid)\n{\n  "
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree/visual_flags.hh",
    "chars": 1504,
    "preview": "#pragma once\n\n#include \"../core.hh\"\n#include <set>\n#include <map>\n\nnamespace cpprofiler\n{\nnamespace tree\n{\n\nclass Visual"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree_builder.cpp",
    "chars": 3498,
    "preview": "#include \"tree_builder.hh\"\n\n#include \"message_wrapper.hh\"\n\n#include \"utils/perf_helper.hh\"\n#include \"utils/debug.hh\"\n#in"
  },
  {
    "path": "cp-profiler/src/cpprofiler/tree_builder.hh",
    "chars": 592,
    "preview": "#pragma once\n\n#include \"message_wrapper.hh\"\n#include <QObject>\n\nnamespace cpprofiler\n{\n\nclass Execution;\n\nclass TreeBuil"
  },
  {
    "path": "cp-profiler/src/cpprofiler/user_data.cpp",
    "chars": 835,
    "preview": "#include \"user_data.hh\"\n\nnamespace cpprofiler\n{\n\nvoid UserData::setSelectedNode(tree::NodeID nid)\n{\n    m_selected_node "
  }
]

// ... and 67 more files (download for full content)

About this extraction

This page contains the full source code of the MiniZinc/MiniZincIDE GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 267 files (1.2 MB), approximately 312.4k tokens, and a symbol index with 1067 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!